子序列定义:将给定序列中零个或多个元素去掉之后得到的结果
比如abcd是abecd的子序列
最长公共子序列问题:给定两个序列X和Y,求两者长度最长的公共子序列
1. 最长公共子序列的特征
X = <x1, x2, ..., xn>,Y = <y1, y2, ..., yn>;Z = <z1, z2, ..., zn>是两者的任意LCS
1) 如果xm = yn, 则zk = xm = yn且Zk-1是Xm-1和Yn-1的一个LCS
2) 如果xm != yn,那么zk != xm 意味着Z是Xm-1和Yn的一个LCS
3) 如果xm != yn,那么zk != yn意味着Z是Xm和Yn-1的一个LCS
2. 递归解
c[i, j]表示Xi和Yj的LCS的长度;则
c[i, j] = 0 若i = 0 或 j = 0
c[i-1, j-1] + 1 若i, j > 0且xi = yj
max(c[i-1, j], c[i, j-1]) 若i, j>0且xi != yj
3. 自底向上计算
4. 构造LCS
可以在自底向上计算过程中,保存子问题最优解
当xi == yj b[i, j] = equal
当c[i-1, j] > c[i, j-1] b[i, j] = left
当
c[i-1, j] < c[i, j-1] b[i, j] = right
从而可以如下构造LCS
PRINT-LCS(b, X, i, j)
if i==0 or j==0
return
if b[i, j] == equal
PRINT-LCS(b, X, i-1, j-1)
print Xi
elseif b[i, j] == left
PRINT-LCS(b, X, i-1, j)
else
PRINT-LCS(b, X, i, j-1)
算法的改进,可以在构造LCS时,直接利用数组c的大小比较来判断,而不需要数组b