【动态规划总结(一)】背景
1. 什么是动态规划
动态规划(英语:Dynamic programming,简称 DP)
动态规划不是某一种具体的算法,而是一种算法思想:若要解一个给定问题,我们需要解其不同部分(即子问题),再根据子问题的解以得出原问题的解。
1.1最优子结构
动态规划要解决的都是一些问题的最优解,即从很多解决问题的方案中找到最优的一个。当我们在求一个问题最优解的时候,如果可以把这个问题分解成多个子问题,然后递归地找到每个子问题的最优解,最后通过一定的数学方法对各个子问题的最优解进行组合得出最终的结果。
总结来说就是一个问题的最优解是由它的各个子问题的最优解决定的。
将子问题的解进行组合可以得到原问题的解是动态规划可行性的关键。在解题中一般用状态转移方程描述这种组合。例如原问题的解为 f(n),其中 f(n)也叫状态。状态转移方程 f(n) = f(n - 1) + f(n - 2)f(n)=f(n−1)+f(n−2) 描述了一种原问题与子问题的组合关系 。在原问题上有一些选择,不同选择可能对应不同的子问题或者不同的组合方式。找到了最优子结构,也就能推导出一个状态转移方程f(n),通过这个状态转移方程,我们能很快的写出问题的递归实现方法。
1.2 重复子问题
重复子问题规定的是子问题与子问题的关系。
当我们在递归地寻找每个子问题的最优解的时候,有可能会会重复地遇到一些更小的子问题,而且这些子问题会重叠地出现在子问题里,出现这样的情况,会有很多重复的计算。
动态规划可以保证每个重叠的子问题只会被求解一次。当重复的问题很多的时候,动态规划可以减少很多重复的计算。
重复子问题不是保证解的正确性必须的,但是如果递归求解子问题时,没有出现重复子问题,则没有必要用动态规划,直接普通的递归就可以了。
例如,斐波那契问题的状态转移方程 f(n) = f(n - 1) + f(n - 2)。在求 f(5) 时,需要先求子问题 f(4)和 f(3),得到结果后再组合成原问题 f(5)的解。递归地求 f(4) 时,又要先求子问题 f(3) 和 f(2) ,这里的 f(3) 与求 f(5)时的子问题重复了,所以用动态规划。
动态规划算法中关于最优子结构和重复子问题的理解的关键点:
- 证明问题的方案中包含一种选择,选择之后留下一个或多个子问题
- 设计子问题的递归描述方式
- 证明对原问题的最优解包括了对所有子问题的最优解
- 证明子问题是重叠的(这一步不是动态规划正确性必需的,但是如果子问题无重叠,则效率与一般递归是相同的)