DP广泛用于求解组合最优化问题。动态规划(Dynamic Tabling)不是递归调用自身,但是问题的基础解通常以递归函数的形式予以说明的。递归是自顶向下,动态规划是自底向上。
- 用来引出递归和归纳的最常见的例子是 斐波那契数列问题
每一个数都是前两个数的和
1 | procedure f(n) |
但是如果自底向上明显能够在n的时间和常数空间
- 另一个类似的例子是二项式系数 如果自顶向下需要的时间复杂度为指数时间复杂度 $O(2^n)$,但是通过构造帕斯卡三角形,能够很快地计算出来。
7.2 LCS 最长公共子序列
在字母表Σ上,分别给出两个长度为m和n的字符串A 和 B,确定在A和B中最长公共子序列的长度。A=”a1a2…Am” B=’b1b2..bn’
为了使用动态规划技术,我们首先寻找一个最长公共子序列长度的递推公式
L[i, j] = L[i-1, j-1] + 1 if ai==bj
L[i,j] = max{L[i-1, j], L[i, j-1]} if ai!=bj
1 | algorithm 7.1 LCS |
如何输出 最长公共子序列?
最长公共子序列可能是有多种长度相同的子序列!!!,如何找出所有的子序列。一个子序列也可能以不同的下标序列出现!
如何找出所有的LCSs?
Side Notes
在DP问题中,也可以利用递归的形式达到DP的时间复杂度。这种递归使用了一张备忘录以记录已被计算过的情况,以避免重叠case的重复调用,因此被称为带备忘录的递归。 —-《算法导论》