众多算法中,动态规划是比较难的算法,难在递归式!一旦得到递归式 ,算法就已经实现99%,剩下的是程序实现问题。
分析原问题最优解和子问题最优解的关系。考查有多少种选择。得到最优解递归式。 以上的理解请不要陷入细节,更多的理解请从实际的案例中体会。问题的重复求解是动态规划提升的关键。
一、问题引入
本题是动态规划算法经典例题。在解决问题之前,让我们回顾解题步骤,然后来一步一步实现。
1.分析最优解的结构特征
解决LCS问题,需要把原问题分解成若干个子问题,所以需要刻画LCS的特征。
设A=“a0,a1,…,am”,B=“b0,b1,…,bn”,且Z=“z0,z1,…,zk”为它们的最长公共子序列。不难证明有以下性质:
如果am=bn,则zk=am=bn,且“z0,z1,…,z(k-1)”是“a0,a1,…,a(m-1)”和“b0,b1,…,b(n-1)”的一个最长公共子序列;
如果am!=bn,则若zk!=am,蕴涵“z0,z1,…,zk”是“a0,a1,…,a(m-1)”和“b0,b1,…,bn”的一个最长公共子序列;
如果am!=bn,则若zk!=bn,蕴涵“z0,z1,…,zk”是“a0,a1,…,am”和“b0,b1,…,b(n-1)”的一个最长公共子序列。
或者直接看图(来自优快云博主「Running07」,博文链接在最后哦):
举个栗子(S1={1,3,4,5,6,7,7,8}和S2={3,5,7,4,8,6,7,8,2}),并结合上图来看:
假如S1的最后一个元素 与 S2的最后一个元素相等,那么S1和S2的LCS就等于 {S1减去最后一个元素} 与 {S2减去最后一个元素} 的 LCS 再加上 S1和S2相等的最后一个元素。
假如S1的最后一个元素 与 S2的最后一个元素不等(本例子就是属于这种情况),那么S1和S2的LCS就等于 : {S1减去最后一个元素} 与 S2 的LCS, {S2减去最后一个元素} 与 S1 的LCS 中的最大的那个序列。
2.建立最优值的递归式。(也可以称为决策策略)
首先,问题来了,如何建立最优值的递推式?
- 定义最优子问题 确定问题的优化目标
- 定义状态 决策的结果(状态) 最终的结果(状态)就是最终解
- 定义决策和状态转换方程 状态递增的表达式(不一定是数学表达式)
- 确定边界条件 实际上就是递归终结条件,无需额外的计算
具体步骤在这里,爷突然发现写博客想面面俱到的讲清楚每一个好难,爷教不会你们了,爷还是老老实实写读书笔记给自己吧QAQ
3.自底向上计算最优值,并记录
4.构造最优解
部分内容参考了这些博客,致谢!指路:
https://so-far-cloud.blog.youkuaiyun.com/article/details/78597963
优快云博主「Running07」的这个图解特别详细