码迷,mamicode.com
首页 > 其他好文 > 详细

最长公共子序列 动态规划

时间:2016-06-02 14:45:55      阅读:245      评论:0      收藏:0      [点我收藏+]

标签:

子序列
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=LCSXm?1Yn?1+<xm=yn>
if xmym,zkxm
LCSXY=LCSXm?1Yn
if xmym,zkyn
LCSXY=LCSXmYn?1

LCSXY=max{LCSXm?1Yn,LCSXmYn?1}

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

情况一:X=<x1,....,xm?1>,Y=<y1,......,yn?1,xm>zk=xm=ynLCSXY=LCSXm?1Yn?1+<xm=yn>

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

情况二和情况三证明略。

子问题重叠性
LCSXm?1Yn?1的子问题LCSXm?2Yn?2
LCSXm?1Yn的子问题LCSXm?2Yn?2

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

C[i,j]=0 if i=0或j=0
C[i,j]=C[i?1,j?1]+1 if i,j>0 and xi=yj
C[i,j]=Max{C[i?1,j],C[i,j?1]} 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
技术分享

最长公共子序列 动态规划

标签:

原文地址:http://blog.csdn.net/niujiabinbin/article/details/51538820

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!