简单暴力到dp的优化(入门篇)

上篇,我们提到,遇到问题,首先根据定义写出笨方法,找出依赖关系(有些题这一步就不太简单,要自己归纳关系),然后进行优化,下面,我们通过几道此方面的经典的,较为简单的二维题目进行讲解。

 

开始根据题来说明:

第一个萌新题

给定数组arr,  arr  中所有的值都为正数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,  再给定一个整数aim 代表要找的钱数,求组成aim 的最少货币数。

  [举例]

  arr=[5,2,3],  aim=20。

  4 张5 元可以组成20 元,其他的找钱方案都要使用更多张的货币,返回4。

arr=[5,2,3],  aim=0。

  不用任何货币就可以组成0 元,返回0。

  arr=[3,5],aim=2。

  根本无法组成2 元,钱不能找开的情况下默认返回-1。

(你要是想贪心就贪吧,反正我不贪)

定义f(a,b)代表的是a面值及之前的货币,组成b元的最少张数。那f(arr[-1],aim)就是我们想求的答案。现在分析,怎样通过前面的状态推出结果?对于货币arr[-1],我们可以一张都不用,那最少张数其实就是f(arr[-2],aim),我们也可以用一张arr[-1],最少张数就可能是f(arr[-2],aim-arr[-1])+1(用之前的钱组成aim-arr[-1]元钱,然后加一张arr[-1]),同理,我们可以用两张arr[-1],或者更多,直到下一个就超过aim的时候。所以我们应该在所有情况中选最小的,

归纳表达式:

f(a,b)=min(f(arr[a-1],b-k*arr[a])+k),k>=0,且b-k*arr[a]>=0

当然,以前也提到过,直接递归我们会有大量重复计算,所以需要记下来之前的结果供我们使用。有两个参数代表现在的状态,所以生成二维表。

l=[[0 for i in range(len(arr))] for i in range(aim+1)]#

我们看,f(arr[a],b)和谁有关?和上一行,也就是arr[a-1]那一行的很多左边元素有关。

所以确定打表顺序,从上到下,从左到右,打表,一个一个打,l[a][b]=min(f(a-1,b-k*arr[a])+k),依次推出l[a][b],右下角就是答案。

 

 

 

但是,还是有相当多的重复计算,我们的l[a][b-arr[a]]其实就是根据除了l[a-1][b]的左边那些元素求的的最小值

所以l[a][b]=min(l[a][b-arr[a]]+1,l[a-1][b])。

 

其实和左边和上边元素相关的背包,还有一些别的题,都是如此。对于本物品,当前决策就是拿或不拿,以前的最优情况

l[a][b-arr[a]]l[a-1][b]已经有了。不用管的。结合当前状态的定义,就明白了。

 

至此,时间优化到严格o(a*b),空间o(a*b),空间还能优化到o(min(a,b)),下一个题讲压缩方法。

第二个萌新题

给一个由数字组成的矩阵,初始在左上角,要求每次只能向下或向右移动,路径和就是经过的数字全部加起来,求可能的最小路径和。

1  3  5  9

8  1  3  4

5  0  6  1

8  8  4  0

路径:1 3 1 0 6 1 0路径和最小,返回12

生成和矩阵相同大小的二维表DP,用来记录当前的最小路径和

(以后也不分析暴力的时间复杂度了)

对于普遍的位置i,j,只有i-1,j和i,j-1这两个位置可以一步走到这里,所以

DP[i,j]=min(DP[i,j-1],DP[i-1,j])+L[i,j]

压缩:我们发现,除了这个位置上本身的数,DP[i,j]只和DP表中左边和上边的值有关,所以可以生成长度为矩阵较小边长一维表,用两层循环。注意顺序,从左向右打表,只有这样,左边的那个元素才是被更新过的,才是本行的左边那个元素。

最左边的DP值是直接累加的,其他位置

For i 0 to 高度:

    For j 0 to 宽度

DP[j]=min(DP[j-1],DP[j])+L[i,j]

时间不变,空间优化到o(较小边长)

 

 第三道萌新题

题干和第一题一样,请返回所有的还钱方法有多少种

经过一二题,应该自己会做了。

(请记住:一般问方法的题目,只需把式子中max或者min改为sum即可)

n=int(input())
dp=[0]*(n+1)
dp[0]=1
tmp=[1,5,10,20,50,100]
for kk in tmp:for i in range(kk,n+1):dp[i]+=dp[i-kk]
print(dp[n])

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/445669.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

简单暴力到dp的优化(初级篇)

一、一维非脑残 1 一个只包含A、B和C的字符串,如果存在某一段长度为3的连续子串中恰好A、B和C各有一个,那么这个字符串就是纯净的,否则这个字符串就是暗黑的。例如:BAACAACCBAAA 连续子串"CBA"中包含了A,B,C各一个&am…

ccpc河北大学生程序设计竞赛dp小总结

近期题目来自校赛,赛前训练,省赛热身,河北ccpc正式比赛。 题目一: 题目描述: 由于第m个台阶上有好吃的薯条,所以薯片现在要爬一段m阶的楼梯. 薯片每步最多能爬k个阶梯,但是每到了第i个台阶&a…

c语言简便实现链表增删改查

注&#xff1a;单追求代码简洁&#xff0c;所以写法可能有点不标准。 //第一次拿c开始写数据结构&#xff0c;因为自己写的&#xff0c;追求代码量少&#xff0c;和学院ppt不太一样。有错请指出 #include <stdio.h> #include <stdlib.h> #include <string.h>…

第一次课 课上代码

第一次课内容 学习心态及注意事项 信心 谦虚 脚踏实地 多动手 python简介 代码量少&#xff0c;简介&#xff0c;易上手&#xff0c;语法要求不过于严格&#xff0c; Python 库。 速度慢&#xff0c; 不可加密。 输出、变量、输入 数据类型&#xff1a;整数、浮点数…

计算机考研专业课只考一科的学校汇总

下列学校专业课只考1门 &#xff08;每项科目下的学校均按照最新学科评估结果由高到低进行排名&#xff09; C语言程序设计 1. 湖南大学 计算机技术&软工专硕&#xff08;信息科学与工程学院&#xff09; 2. 中国海洋大学 计算机技术&#xff08;01计算机应用技术方向&am…

数组实现栈

学习了改进&#xff0c;利用define typedef比上次写的链表更容易改变功能&#xff0c;方便维护&#xff0c;代码更健壮。 大佬别嫌弃&#xff0c;萌新总是很笨&#xff0c;用typedef都想不到。 #include<stdio.h> #include<stdbool.h> #define maxsize 10 typede…

简单暴力到dp的优化(中级篇)

下面再放三道我比较喜欢的&#xff0c;需要好好写一下的题。 第一题比较水 1. White Cloud is exercising in the playground. White Cloud can walk 1 meters or run k meters per second. Since White Cloud is tired,it cant run for two or more continuous seconds. Whi…

第二次课 课上代码

敲一遍&#xff0c;体会每行代码想表达的意思。 第二讲 创建.py文件 数据类型&#xff1a;布尔(and\or\not) 条件判断语句(if elif else) 列表基础操作&#xff08;特点、创建、增加元素、len()、下标、py切片&#xff09; >>> 5>4 True >>> 4>5 Fa…

第一次课 优秀作业展示

18级河北师大软件编程训练 很多同学非常认真的完成了作业&#xff0c;这里选出比较优秀的作业展示出来。 注&#xff1a;展示顺序不是排名 为了尊重同学们的劳动成果&#xff0c;并没有要代码&#xff0c;只是截图展示。 范天祚 &#xff08;傻兔子&#xff09; 熊静祎&…

dp打开思路:HDU1029 HDU1087 HDU1176 HDU1257 POJ1458(水题不水)

题目&#xff1a;https://vjudge.net/contest/68966#overview HDU - 1029 题意&#xff1a;找出出现次数超过一半的数字 蠢思路&#xff1a;排序找中间 DP&#xff1a;扫一遍一个变量count记录解出现的次数&#xff0c;是当前解就&#xff0c;否则--&#xff0c;count为负就…

dp打开思路2:POJ2533 HDU1114 HDU1260 HDU1160(水题不水)

题目&#xff1a;https://vjudge.net/contest/68966#overview POJ2533 最长上升子序列&#xff0c;很平常的题&#xff0c;但是维持单调队列二分还是值得一贴的&#xff0c;O(nlogn) 关键思想&#xff1a;出现在单调队列里的数都在当前接收的数之前&#xff0c;所以找到最小…

二分查找及一般拓展总结

二分-不止是查找哦 二分过程&#xff1a;首先&#xff0c;假设表中元素是按升序排列&#xff0c;将表中间位置记录的关键字与查找关键字比较&#xff0c;如果两者相等&#xff0c;则查找成功&#xff1b;否则利用中间位置记录将表分成前、后两个子表&#xff0c;如果中间位置记…

第三次课 课上代码

这次可能比较简短&#xff0c;这样也好&#xff0c;可读性比较强。 别问我为什么&#xff0c;我不会告诉你们我把代码关了的哼哼。 简单复习、注意事项及小知识强调讲解 作业讲解 列表的遍历 For循环&#xff08;这个参考切片&#xff0c;视频有详细讲解&#xff0c;一样的…

排序算法基本介绍及python实现(含详细注释)

对数组排序可以说是编程基础中的基础&#xff0c;本文对八种排序方法做简要介绍并用python实现。 代码中注释很全&#xff0c;适合复习和萌新学习。这是刚入学自己写的&#xff0c;可能难免比不上标准的写法&#xff0c;但是懒得改了。 文末会放和排序相关的基本拓展总结链接…

第二次作业 讲解及展示

第二次作业&#xff0c;同学们虽然在认真完成&#xff0c;但是或多或少都出了一些错误&#xff0c;一班张婷&#xff0c;四班武仪人&#xff0c;六班杨泽宇&#xff0c;八班候雯洁&#xff0c;安锦阳&#xff0c;刘净圆&#xff0c;这些同学完成的较为出色&#xff0c;错误较少…

深搜DFS\广搜BFS 图初步入门

首先&#xff0c;不管是BFS还是DFS&#xff0c;由于时间和空间的局限性&#xff0c;它们只能解决数据量比较小的问题。 深搜&#xff0c;顾名思义&#xff0c;它从某个状态开始&#xff0c;不断的转移状态&#xff0c;直到无法转移&#xff0c;然后退回到上一步的状态&#xf…

素数基本(埃氏筛法/线性筛法)

一、检查n是否为素数 最简单思路&#xff1a;所有可能的因数全部试一遍。 int gg(int n) {for(int i2;i<n;i){if((n%i)0)return 0;//有因数就不是素数咯}return 1; } 进一步思考&#xff1a;没必要枚举所有的数&#xff0c;每一个小于n^(1/2)的因数i&#xff0c;一定有一个大…

欧几里得gcd/extend_gcd

正式叙述前还写了一点自己的小感受。 问题&#xff1a;求两个正整数a&#xff0c;b的最大公约数。 大神看来是很简单的问题&#xff0c;但是对于去年夏天刚学python的我来说&#xff0c;这是个很难的问题&#xff0c;还记得当时一晚上睡不着都在想怎么快一点的求出最大公约数…

python基础技巧总结(一)

最近总结一下python基础知识&#xff0c;就暂时弃坑了。 本文总结只属于python的一些骚操作。。。 后面文章自行去博客学习交流 原地交换 Python 提供了一个直观的在一行代码中赋值与交换&#xff08;变量值&#xff09;的方法 x, y 10, 20 print(x, y)x, y y, x print(x…

python基础技巧总结(二)

一总结的链接&#xff1a; 好&#xff0c;我们继续 一次性初始化多个变量 可以直接赋值&#xff1a; a,b,c,d1,2,3,4 可以利用列表&#xff1a; List [1,2,3] x,y,zList print(x, y, z) #-> 1 2 3 &#xff08;元素个数应与列表长度相同&#xff09; 打印模块路径 im…