动态规划类型题目的特点:
1、基本上为科技公司面试必考算法
2、题目类型多,没有固定模板
3、难度属于中上
动态规划题目特点:
- 计数
1、有多少种方式
2、有多少种方法选出K个数使得和是sum - 求最大最小值
1、从左上角到右下角路径的最大数字和
2、最长上升子序列长度 - 求存在性
1、取石子游戏,先手是否必胜
2、能不能选出K个数使得和是sum
解题过程
例题:你有三种硬币,分别面值为2元,5元和7元,每种硬币都有足够多,买一本书需要27元,如何用最少的硬币组合正好付清,不需要对方找钱
- 确定状态
简单的说,解动态规划的时候需要建立一个数组,数组的每个元素arr[i]或者arr[i][j]代表什么
确定状态需要两个意识:最后一步和子问题
最后一步:虽然我们不知道最有策略是什么,但是最优策略肯定是K枚硬币a1,a2,…,ak面值加起来等于27,所以一定有一枚最后的硬币ak,除掉这枚硬币,前面的硬币的面值加起来是27-ak。也就是说用K-1枚硬币拼出27-ak
子问题:如何用K-1枚硬币可以拼出27-ak。而且ak只能是2,5或者7
设f(X) = 最少用多少枚硬币拼出X
如果ak是2,f(27)=f(27-2)+1(加上最后这一枚硬币2)
如果ak是5,f(27)=f(27-5)+1(加上最后这一枚硬币5)
如果ak是7,f(27)=f(27-7)+1(加上最后这一枚硬币7)
最少的硬币数:
f(27)=min{ f(27-2)+1,f(27-5)+1,f(27-7)+1 }
-
转移方程
f[27]=min{ f[27-2]+1,f[27-5]+1,f[27-7]+1 } -
初始条件和边界情况
用转移方程算不出来,但是计算又需要,就需要手动定义为初始条件
边界情况就是保证数组不要越界
如果拼不出X,定义f[X]=正无穷
f[1]=min{ f(-1)+1,f(-4)+1,f(-6)+1 }=正无穷,表示拼不出来1
f[0]=0 -
计算顺序
f[27]=min{ f[27-2]+1,f[27-5]+1,f[27-7]+1 }
f[0]=0
由此然后计算f[1],f[2]…f[27]
顺序确定原则:当我们计算到f[X]时,f[X-2],f[X-5],f[X-7]都已经取得结果了
小结
-
确定状态
最后一步
化成子问题 -
转移方程
f[27]=min{ f[27-2]+1,f[27-5]+1,f[27-7]+1 } -
初始条件和边界情况
f[0]=0,如果拼不出定义为无穷大 -
计算顺序
f[0],f[1],f[2]…