适合应用动态规划方法求解的最优化问题应该具备两个要素:最优子结构和子问题重叠
1. 最优子结构
判断依据
如果一个问题的最优解包含其子问题的最优解,此问题具有最优子结构性质。
发掘最优子结构性质的通用模式
- 证明问题最优解的第一个组成部分是做出一个选择,做出这次选择会产生一个或多个问题;
- 对于一个给定的问题,在其可能的第一步选择中,假定知道哪种选择是最优的;
- 给定可获得最优解的选择后,确定本次选择会产生的子问题,以及如何最好的刻画子问题空间。
- 作为构成原问题最优解的组成部分,每个子问题的解就是它本身的最优解。
对于不同的问题领域,最优子结构的不同体现在两个方面
- 原问题的最优解中涉及多少个子问题;
- 在确定最优解使用哪些子问题时,我们需要考虑多少种选择。
同时,子问题的总数和每个子问题需要考察多少种选择这两个因素的乘积来粗略分析动态规划算法的运行时间。
注意
原问题是否具有最优子结构,还需要考虑子问题的无关性。即同一个原问题的一个子问题的解不影响另一个子问题的解。
2. 重叠子问题
适合用动态规划方法求解的最优化问题应该具备的第二个性质是子问题空间必须足够“小”,即问题的递归算法会反复地求解相同的子问题,而不是一直生成新的子问题。一般来讲,不同子问题的总数是输入规模的多项式函数为好。如果递归算法反复求解相同的子问题,就称最优化问题具有重叠子问题性质。
这里需要与最优子结构的子问题的无关性区分开来,子问题重叠是指子问题求解方式是可复用的,即可以递归反复求解。而子问题无关性是针对子问题的解来说的,一个子问题的解不影响另一个子问题的解。重叠子问题强调求解过程,子问题无关性强调解的影响。
意义
动态规划通常利用重叠子问题的性质:对于每个子问题只求解一次,并将解存入一个表中(通常是一个一维或者二维数组),当再次需要这个子问题时直接查表,每次查表的代价为常量时间(利用数组下标直接访问对于元素)