绪论
最后三章的内容联系前面的贪心算法主要介绍几类算法(问题,思想),这一章节介绍动态规划。和贪心一样,动态规划不是某个算法,而是一种解决问题的思路,我们在前面介绍过的算法(例如Bellman-ford算法)中就有很多用到这个算法思想的。
事实上在重新讨论了贪心算法的整体思路后,我觉得应该按照介绍最短路算法那里的顺序介绍贪心和动态规划(先介绍动态规划再介绍贪心)。
Dynamic programming
Dynamic programming,也就是我们常说的DP,就是指动态规划,那什么叫做动态规划呢?
课件中以求解Fibonacci数为例:如果我们想要计算出前20个Fibonacci数,求第i个Fibonacci数需要知道第i-1个Fibonacci数和第i-2个Fibonacci数的值,高效的做法是将前i-1个Fibonacci数的值全部存储下来,再求解第i个Fibonacci,而不是在每次求解第i个Fibonacci数时,重复的计算前面i-1个Fibonacci数的值。
Bellman-ford算法求解最短路也是一个动态规划的例子:第k个阶段求解长度为k的最短路径,然后将第k个阶段扩展到第k+1个阶段。
从目的来看,这样设计算法是为了减少求解一个问题中很多子问题(阶段)的重复计算(Bellman-ford算法考虑到了结点最短路径之间的可继承性),实现时通过将每个阶段的值存储下来从而避免这个阶段重复的计算(用空间换时间)。
结合到框架来看,上述问题都可以划分成若干个阶段,每个阶段求解的过程依赖于前面阶段的解(Bellman-ford算法)或者说可以通过前面阶段的解来减少当前阶段计算的次数(Fibonacci数),最后一个阶段得到我们整个问题的解(Fibonacci数的第i个阶段为求前i个Fibonacci数)。
满足上述条件的问题我们称为多阶段决策问题,用上述框架设计出来解决该类问题的算法我们称为动态规划方法。
贪心算法和动态规划的区别就在于从某个阶段扩展到后面阶段时,扩展的方向考虑某些经验背景下当前情况的最优解,而放弃其他可能方向的扩展(不讨论所有的可能)。
我们没有介绍(也不会在这个专栏介绍)的分治法和动态规划的区别则在于,分治法的子问题是独立的,且需要子问题合并之后才能得到最终解,而动态规划的阶段是一层一层向外扩展的。
分析贪心算法和动态规划的区别时,我们同时可以知道:设计动态规划算法的策略和框架与贪心算法基本是相同的,除去扩展时根据经验只考虑最优解的一步(如果能证明局部的最优解能够达到实际最优解,那这就是贪心算法了,我是这么看待两个算法的区别和关系的)。
Weighted interval scheduling
贪心法中有一个区间调度问题,这