动态规划 ------- 最长公共子序列

一个给定序列的子序列是在该序列中删去若干元素后得到的序列。确切说,若给定序列 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={x1,x2,....,xm}和Y={y1,y2,...,yn},找出X和Y的最长公共子序列。

 

1.最长公共子序列的结构

 

   穷举搜索法是最容易想到的算法,对X的所有子序列,检查它是否也是Y的子序列,从而确认它是否为X和Y的公共子序列。并且在检查过程中记录最长的公共子序列。X的所有子序列都检查后即可求出X和Y的最长公共子序列。但需要指数时间O(2m)。

 

 最长公共子序列问题具有最优子结构性质。设序列X={x1,x2,....,xm}和Y={y1,y2,...,yn}的最长公共子序列为Z ={z1,z2,....,zk},则

  (1) 若 xm ==yn   则zk =xm = yn,且Zk-1是Xm-1 和Yn-1的最长公共子序列。

  (2) 若 xm !=yn    且zk != xm ,则Z是Xm-1 和Y的最长公共子序列。

  (3) 若 xm !=yn    且zk != yn   ,则Z是X 和Yn-1的最长公共子序列。

 其中,Xm-1 = {x1,x2,....,xm-1}; Yn-1 ={y1,y2,...,yn-1};Zk-1={z1,z2,....,zk-1};

 

 

 2,子问题的递归结构

    

  由最长公共子序列问题的最优子结构性质可知,要找出X ={x1,x2,....,xm}和Y={y1,y2,...,yn}最长公共子序列,可以按一下方式递归进行:当 xm ==yn 时,找出Xm-1 和 Yn-1  的最长公共子序列,然后在其尾部加上xm (==yn )即可得X和Y的最长公共子序列。当xm !=yn  时,必须解决两个子问题,即找出Xm-1 和Y的最长公共子序列及Yn-1 和X的最长公共子序列。这两个公共子序列中较长者即为X和Y的最长公共子序列。

  由此递归结构容易看到,最长公共子序列问题具有子问题重叠性质。例如,在计算X和Y的最长公共子序列时,可能要计算X和Yn-1 及Xm-1 和Y的最长公共子序列。而这两个子问题都包含一个公共子问题,即计算Xm-1 和Yn-1的最长公共子序列。

    首先建立子问题最优值的递归关系。用c[i][j]记录序列Xi 和Yj 的最长公共子序列的长度。其中Xi ={x1,x2,....,xj};Yj={y1,y2,...,yj}。当i=0 或j =0时,空序列是Xi 和Yj 的最长公共子序列。故此时c[i][j]=0;其他情况下,由最优子结构性质可建立递归关系如下:

 

   c[i][j] = 0  i=0,或 j=0; c[i][j] = c[i-1][j-1] +1  i,j>0;xi=yj; c[i][j] = max{c[i][j]-1],c[i-1][j]}  i,j>0;xi !=yj

 

3  计算最优值i

      直接利用递归式容易写出计算c[i][j]的递归算法,但其计算时间是随输入长度指数增长的。由于在所考虑的子问题空间中,总共有@(m*n)个不同的子问题,因此用动态规划算法自低向上计算最优值能提高算法的效率。

 

       b[i][j] 记录 c[i][j]的值是由哪一个子问题的解得到的,这在构造最长公共子序列时要用到。问题最优值,即X和Y的最长公共子序列的长度记录与c[i][j];

 

  

 

LCSlength耗时O(mn)。

 

4。构造最长公共子序列

   

 

 

    

 

 

阅读更多
文章标签: zk 算法 c
个人分类: 算法 和 数据结构
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭