动态规划
动态规划算法是通过拆分问题,定义问题状态和状态之间的关系,构建状态变化方程使得问题能够用递推的方式去解决。
动态规划算法的基本思想是将待求解的问题分解为若干个子问题(一般是按照时间,阶段,空间划分),按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息,并且每次都保存了前面问题的结果,每次使用的时候可以直接调用,不必再次遍历,可以节省时间。在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。依次解决各子问题,最后一个子问题就是初始问题的解。
但是,我感觉动态规划很难,每次做题都要考虑好久。或许真的是需要一步步的来,多做题,多分析才可以弄懂吧。
也总结出一些做题的小技巧吧
- 每次做题把问题分阶段,确定每一个问题的状态,以及前后的关系。
- 通过前后的关系,找出状态转移方程(总是很难找出)
- 确定状态转移方程的边界条件,毕竟状态转移方程和递归的思路差不多,需要停止。
- 一般是最后一个存储的结果就是所要找的最优解。
常见的题型:
- 最长公共子序列
分析:
(1)确定状态:
设f[x][y]表示s[1–x]和t[1–y]的最长公共子序列的长度
(2)确定方程与边界条件:
•s[x]不在公共子序列中,该情况下
f[x][y]=f[x-1][y];
•t[y]不在公共子序列中,该情况下
f[x][y]=f[x][y-1];
•s[x]==t[y],s[x]和t[y]在公共子序列中,
f[x][y]==f[x-1][y-1]+1;
f[x][y]取三种情况的最大值。
状态转移方程:
f[x][y]=max{f[x-1][y],f[x][y-1],f[x-1][y-1]+1}
边界条件:
f[0][y]=0;f[x][0]=0;
(3)程序的实现:
按照行从小到大,同一行按列从小到大计算,迭代即可。 - 走方格问题
描述:
有一个矩阵,它每个格子有一个权值。从左上角的格子开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的数字累加起来就是路径和,返回所有的路径中最小的路径和。
解题思路:
设dp[n][m]为走到n*m位置的路径长度,那么显而易见
dp[n][m] = min(dp[n-1][m],dp[n][m-1]);
边界条件:dp[1][1]=第一个格子的权值。 - 最大子矩阵和
二维数组的子矩阵求其中最大的和。
可以进行降维计算,如果是二维数组而又去遍历每一个子矩阵很容易超时,降维之后,就是一个最大子段和的问题。
动态规划的题目很难,但是要坚持去做,去看,搞清楚例题,多做题总结,强化训练才能成功。