算法导论动态规划总结

适合应用动态规划解决的问题具备两个要素:最优子结构和子问题重叠。

最优子结构:

如果一个问题的最优解包含了其子问题的最优解,我们就称此问题具有最优子结构。使用DP的过程中,我们用子问题的最优解来构造原问题的最优解。

例如,在矩阵链乘法问题中,计算矩阵乘法A1*A2*...*An最少运算次数,假设(A1*A2*...*Ak)*(A(k+1)*...*An)具有最少运算次数,那么我们下一步的目标就是求A1*...*Ak和A(k+1)*...An的最少运算次数(子问题的最优解),随后通过我们求解的子问题的最优解来得到原问题的最优解(总运算次数最少)。

发掘最优子结构的过程中,实际遵循了如下的一个模式:

1、证明问题最优解的第一个组成部分是做出一个选择。例如矩阵链乘法中,选择k。这次选择会产生一个或多个子问题(两个更小的矩阵链最少运算次数)。

2、假定已经知道这个选择是最优选择,我们暂时还不关心这个选择是如何得到的。

3、针对这个最优的选择(矩阵链乘法中的选择k),看看会产生哪些子问题(两个更小矩阵链的最优解),在假定知道这个最优选择的情况下,确定递推公式。

4、确定如何得到最优选择(一般来说是遍历),在矩阵链乘法问题中,通过遍历,针对每种选择求解最少的运算次数,从而确定了原问题的最少运算次数。

刻画子问题空间的好经验是:保持子问题空间尽可能简单。

对于不同问题领域,最优子结构的不同体现在两个方面:

1、原问题的最优解中涉及多少个子问题(矩阵链乘法中涉及两个子问题)

2、在确定最优解使用哪些子问题的时候,需要考虑多少种选择(上例中需要考虑n种选择)

我们可以用子问题的总数和每个子问题需要考察多少种选择这两个因素粗略分析动态规划算法的运行时间:矩阵链乘法中有n^2个子问题(更小矩阵链运算次数最少),每个子问题最多需要考察n-1种选择,所以矩阵链乘法的运行时间为n^3.

动态规划算法中,通常自底向上地求解最优子结构,首先求得子问题的最优解,在求解原问题的过程中,需要在涉及的子问题中进行选择,选择出能够得到原问题最优解的子问题。

重叠子问题:

动态规划问题的另外一个特征是:问题的递归算法会反复求解相同的子问题。如果递归算法反复求解相同的子问题,我们就称最优化问题具有重叠子问题。

在矩阵链乘法的过程中,我们需要计算不同划分方案的最少运算次数,并选择最小值:

首先计算A1和A2*...An最少运算次数,在递归求解A2*...*An最少运算次数的过程中,需要求解A4*...*An的最少运算次数。接着计算A1*A2和A3*...*An的最少运算次数,在递归求解A3*...*An最少运算次数的过程中,又要求解A4*...*An的最少运算次数,便造成了大量重复计算。往往这种重复计算会造成指数级别的时间复杂度。

猜你喜欢

转载自blog.csdn.net/LOVETEDA/article/details/85039168