最长公共子序列问题-动态规划
一个给定序列的子序列是在该序列中删去若干元素后得到的序列。确切地说,若给定序列X={x1,x2,…,xm},则另一序列Z={z1, z2,…,zk},是X的子序列是指存在一个严格递增下标序列{i1, i2,…, ik}使得对于所有j=1,2,…, k,有: zj=xij。例如,序列Z={B,C, D,B}是序列X={A,B,C,B,D,A,B}的子序列,相应的递增下标序列为{2,3,5,7}。
给定两个序列X和Y,当另一个序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。
例如,若X={A,B,C,B,D,A,B},Y={B, D,C,A,B,A},则序列{B,C,A}是X和Y的一个公共子序列,但它不是X和Y的一个最长公共子序列。序列{B,C,B,A}也是X和Y的一个公共子序列,其长度为4,而且它是X和Y的最长公共子序列,因为X和Y没有长度大于4的公共子序列。
穷举搜索法是最容易想到的算法,对X的所有子序列,检查它是否也是Y的子序列。从而确定它是否为X和Y的公共子序列。并且在检查过程中记录最长的公共子序列。X的所有子序列都检查过后即可求出X和Y的最长公共子序列。X的每个子序列相应于下标集{1,2, …,m}的一个子集,因此有2m个不同子序列,从而穷举搜索法需要指数时间。
事实上,最长公共子序列问题具有最优子结构性质。
设序列X={x1,x2, …, xm}和Y={y1,y2, …,yn}的最长公共子序列为Z={z1,z2, …,zk},则
①若xm=yn, 则zk=xm=yn, 且Zk-1是Xm-1和Yn-1的最长公共子序列。
②若xm≠yn,且zk≠xm,则Z是Xm-1 和Y的最长公共子序列。
③若xm#yn且zk#yn,则Z是X和Yn-1的最长公共子序列。 其中,Xm-1={x1,x2, …,xm-1},Yn-1={y1,y2, …,yn-1},Zn-1={z1,z2, …,zk-1}。
由最长公共子序列问题的最优子结构性质可知,要找出X={x1,x2,…,xm}和Y={y1, y2,…,yn}的最长公共子序列,可按以下方式递归地进行:
1.当xm=yn,时,找出Xm-1和Yn-1的最长公共子序列,然后在其尾部加上xm (xm=yn),即可得X和Y的最长公共子序列。
2.当xm≠yn,时,必须解两个子问题,即找出Xm-1和Y的一个最长公共子序列及X和Yn-1的一个最长公共子序列。这两个公共子序列中较长者即为X和Y的最长公共子序列。
由此递归结构容易看到,最长公共子序列问题具有子问题重叠性质,即计算Xm-1和Yn-1的最长公共子序列。
首先建立子问题最优值的递归关系,用c[i][j]记录序列Xi和Yj的最长公共子序列的长度。其中,Xi={x1,x2,…,xi}:Yj={y1,y2,…,yj},当i=0或j=0时,空序列是Xi和Yj的最长公共子序列。
所以,此时c[i][j]=0。其他情况下,由最优子结构性质可建立递归关系如下:



1 | /** |