最长公共子序列 动态规划

来源:互联网 发布:it服务是什么 编辑:程序博客网 时间:2024/06/15 05:10

子序列
X=(A,B,C,B,D,B)
W=(B,D,A)XNO
Z=(B,C,D,B)XYES

公共子序列
ZXYZXY

最长公共子序列
输入:X=(x1,x2,.....,xm),Y=(y1,y2,...,yn)
输出:X与Y的最长公共子序列Z=(z1,z2,....,zk)

最长公共子序列结构分析
第i前缀
X=(x1,x2,.....xn)
Xi=(x1,.....,xi)是X的第i前缀

例:X=(A,B,D,C,A),X1=(A),X2=(A,B),X3=(A,B,D)

优化子结构的猜想
XYLCSLCSXY=(z1,....,zk)
if xm=yn
LCSXY=LCSXm1Yn1+<xm=yn>
if xmym,zkxm
LCSXY=LCSXm1Yn
if xmym,zkyn
LCSXY=LCSXmYn1

LCSXY=max{LCSXm1Yn,LCSXmYn1}

优化子结构的证明
思路:对于LCS问题,把最优解分解成两部分,且保证子问题无关性,对两部分分别用反正法,即假定两个子问题的最优解不是最优的,通过“剪切粘贴”构造另一个子最优解,把构建后的子最优解粘贴到原问题中,得出矛盾。

情况一:X=<x1,....,xm1>,Y=<y1,......,yn1,xm>zk=xm=ynLCSXY=LCSXm1Yn1+<xm=yn>

证明 设Z=Zk1+Zk是X和Y的一个最长公共子序列。
zkxm可加xm=yn到Z,得到一个长为k+1的X与Y的公共序列,与Z是最长公共子序列LCS矛盾,于是,zk=xm=yn,
Zk1LCSXm1Yn1
存在Xm1Yn1的公共子序列Z’,|Z|>|Zk1|
于是|Z+<xm=yn>|>|LCSXY=Zk1+<xm=yn>|
LCSXY是LCS矛盾。

情况二和情况三证明略。

子问题重叠性
LCSXm1Yn1的子问题LCSXm2Yn2
LCSXm1Yn的子问题LCSXm2Yn2

建立LCS长度的递归方程
C[i,j]=XiYjLCS
LCS

C[i,j]=0 if i=0或j=0
C[i,j]=C[i1,j1]+1 if i,j>0 and xi=yj
C[i,j]=Max{C[i1,j],C[i,j1]} if i,j>0 and xiyj

自底向上计算优化解代价
C[0,0] C[0,1] C[0,2] C[0,3] C[0,4]
C[1,0] C[1,1] C[1,2] C[1,3] C[1,4]
C[2,0] C[2,1] C[2,2] C[2,3] C[2,4]
C[3,0] C[3,1] C[3,2] C[3,3] C[3,4]

如果想要计算C[3,4],需要先计算
C[2,3] C[2,4]
C[3,3]

如果要计算C[2,3],需要计算
C[1,2] C[1,3]
C[2,2]

如果要计算C[3,3] ,需要计算
C[2,2] C[2,3]
C[3,2]

……..所以最先要计算的是
C[0,0] C[0,1] C[0,2] C[0,3] C[0,4]
C[1,0]
C[2,0]
C[3,0]

之后根据递归公式逐行计算
C[0,0] C[0,1] C[0,2] C[0,3] C[0,4]
C[1,0] C[1,1]C[1,2]C[1,3]C[1,4]
C[2,0] C[2,1]C[2,2]C[2,3]C[2,4]
C[3,0] C[3,1]C[3,2]C[3,3]C[3,4]

计算LCS长度的算法
数据结构:
C[0:m,0:n]:C[i,j]XiYjLCS
C[1:m,1:n]:B[i,j]
这里写图片描述

这里写图片描述

构造最优解
从B[m,n]开始按指针搜索
若B[i,j]="",则xi=yjLCS
如此找到的LCS是X与Y的LCS的Inverse
这里写图片描述

1 0
原创粉丝点击