动态规划整理知识点
一:动态规划作用
1.计数
2.求最值
3.矩阵连乘问题
二:算法要素
1.最优子结构
问题的最优解包含其子问题的最优解
注意:最优子结构是动态规划的最基本的条件,必须有,如果没有,就不能用动态规划。
2.子问题重叠
求解过程中,会出现很多子问题会重复,但是这些重复的子问题只需要解一次,所以酒醋要吧求得的结果存储在表中,以后可以直接查询,不需要再次求解
三:解题步骤(计数问题)
1.确定状态
两个核心:最后一步 、化成子问题
2.转移方程
3.开始和边界条件
4.计算顺序
例题(计数问题):
有三种硬币,面值为2元,5元和7元,每种硬币都有足够多,现买一本书需要27元,如何用最少的硬币组合正好付清而且不需要对方找钱
拿到这题,用我们普通的想法来看有27元,先看最大的7,最多可用3个,然后再用一个5元的,欸,这时我们会发现这样并不行,然后我们又想3个7元的,3个2元的(6枚硬币),这时候正好付清,但是这并不是最优解,最优解应该是1个7元,4个5元.就像这样,如果我们没有正确的方法,我们就需要一直不断地去实验,直到所有结果出来,才可以知道最优解是什么,这样太浪费时间,就此,我们引出
动态规划
的办法来解决这个问题。
1.确定状态
1.1最后一步
我们设定最后一枚硬币的面值为x,则前面所有硬币的面值为27-x。总共有y枚硬币
1.2化解子问题
-
现在我们就要想y-1什么时候最小并且可以拼出面值27-x。
-
这样我们就将大问题转换成了一个小问题,并且规模比他小。
-
这里我们设f(z)=最少用几枚硬币拼出z
-
第一种情况:x=2,f(27)=f(25)+1
-
第二种情况:x=5,f(27)=f(22)+1
-
第三种情况:x=7,f(27)=f(20)+1
这样我们就可以求这三种情况的最小值,就是最优解。
2.确定转移方程:
f[z]=min{ f[z-2]+1, f[z-5]+1, f[z-7]+1}
3.确定开始和边界条件
- 初始条件:z=0 f[0]=0
- 边界问题:z-2,z-5,z-7 小于0 怎么办?什么时候停下来。
- 如果得不到答案,结果等于正无穷
4.计算(从小到大,自底向上)
-
拼出x所需最少硬币数:f[z]=min{ f[z-2]+1, f[z-5]+1, f[z-7]+1}
-
初始条件:z=0 f[0]=0
-
计算f[1],f[2]…f[27]
-
最后算到f[z]的时候,前面那几个值肯定已经算出来了。
其实就是先算f[1],然后记住结果,算后面的就找前面的拼凑,什么时候拼凑到所需要的数值了,什么时候停止。到这里就算进行完成了,编写代码就可以了。
原文章:更详细的原大佬