动态规划原理
动态规划方法通常用来求解最优化问题
- 具有最优子结构
- 子问题重叠
最优子结构
如果一个问题的最优解包含其子问题的最优解,那么就称此问题具有最优子结构性质。某个问题是否适用动态规划方法,观察其是否具有最优子结构性质是一个好的线索(具有最优子结构性质也可能意味着适用贪心策略)。实际上,发掘最优子结构性质遵循如下的通用模式:
- 证明问题最优解的第一个部分是做出一个选择。做出这次选择会产生一个或多个待解的子问题。
- 对于一个给定的问题,在其可能的第一份选择中,假定你已经知道哪种选择会得到最优解。也就是说,不关心这种选择怎么得到的,只是假定知道了这种选择。
- 给定可获得最优解的选择后,你确定这次选择会产生哪些子问题,以及如何最好的刻画子问题空间。
- 利用cut-and-paste技术证明:每个子问题的最优解就是原问题最优解的一部分。反证:假定子问题的最优解不是原问题最优解的一部分,那么我们就从原问题的解中cut这些非最优解,将新的最优解paste上去,从而得到原问题一个更优的解,这与第二步假设的某种选择会得到原问题的最优解相矛盾。
不同问题的最优子结构的不同体现在两个方面:
- 原问题的最优解涉及多少子问题(构成一个子问题空间)
- 对每一子问题,我们需要考察多少种选择。
应用动态规划方法的4个步骤:
- 寻找最优子结构
- 利用子问题的最优解递归定义原问题的最优解
- 选择自底向上表格法或带备忘的自顶向下方法计算各个子问题的最优解(这也是动态规划的编程核心,让时间复杂度很高的递归方法降阶)
- 利用计算得到的子问题的最优解及相关信息,构造原问题的最优解
自底向上表格法:
这种方法一般需要恰当的定义子问题的规模的概念,使得任何子问题的求解都是依赖更小的“子”问题的求解。因而我们需要将子问题按照规模排序,由小至大依次求解。当求解某个子问题时,它所依赖的子问题的解已经求解完毕,且结果都被保存。
带备忘的自顶向下方法:
此方法仍按照自然的递归形式编写函数,但每次函数执行都会保存每个子问题的解(通常被保存在一个数组或散列表里)。当需要一个子问题的解时,函数中先去检查改解是否被保存过。如果是,则直接返回被保存的结果;否则,递归计算该问题的解。

浙公网安备 33010602011771号