动态规划:用来求解多阶段决策的最优化问题,其题目类型多,没有固定模板,难度中上。
1. 动态规划的设计思想
动态规划法将待求解的问题分解成若干个相互重叠的子问题,每个子问题对应决策的一个阶段。一般来说,子问题的重叠关系表现在对给定问题求解的递推关系(称之为动态规划函数)中。
一般来说,动态规划法的求解过程可分为以下四个阶段:
- 确定状态。
- 转移方程
- 初始条件和边界情况
- 计算顺序
2.动态规划题目特点
- 计数
- 有多少种方式走到右下角 - 有多少种方法选出k个数使得和是Sum
- 求最大最小值
- 从左上角走到右下角路径的最大数字和 - 最长上升子序列长度
- 求存在性
- 取石子游戏,先手是否胜利 - 能不能选出k个数使得和是Sum
3.例题 Coin Change–最大最小动态规划
分析:
例子:coins = [2,5,7],amount = 11.
1. 确定状态:
- 最后一步(最优策略中使用的最后一枚硬币a).
- 化成子问题(最少的硬币拼出更小面值27-a)
设状态f[X]=最少用多少枚硬币拼出X;
2. 转移方程:f[X] = min{f[X-2]+1,f[X-5]+1,f[X-7]+1};
3. 初始条件和边界情况:
- 初始条件: f[0] = 0;
- f[X] = min{f[X-2]+1,f[X-5]+1,f[X-7]+1};
- 两个问题:X-2,X-5或X-7小于0怎么办?什么时候停下来?
- 如果不能品出Y,则f[Y]=正无穷。
4. 计算顺序:
初始条件:f[0] = 0,
计算,f[1],f[2]......f[X];
代码:
int CoinChange(int[] A, int M) {
int[] f = new int[M+1];
int n = A.length;
f[0] = 0;
int i,j;
for(i