动态规划

来源:互联网 发布:雷洋事件 知乎 编辑:程序博客网 时间:2024/05/17 13:08

  最长公共子序列问题:

伪代码:

  1. Procedure LCS_LENGTH(X,Y);LCS_LENGTH(X,Y);
  2. begin 
  3.    m:=length[X];
  4.    n:=length[Y];
  5. for i:=to m do c[i,0]:=0;
  6. for j:=to n do c[0,j]:=0;
  7. for i:=to m do 
  8.    for j:=to n do 
  9.       if x[i]=y[j] then 
  10.         begin
  11.            c[i,j]:= c[i-1,-1]+ 1; 
  12.            b[i,j]:="↖"; 
  13.         end 
  14.       else if c[-1,j]≥ c[i,-1then
  15.         begin
  16.            c[i,j]:c[i-1,j];
  17.            b[i,j]:"↑" ; 
  18.         end 
  19.       else 
  20.         begin 
  21.            c[i,j]:c[j-1];
  22.            b[i,j]:="←" 
  23.         end;
  24.    return(c,b);
  25. end

在这个问题中图示:

在LCS算法中,每一次递归调用使i或j减1,因此算法的时间复杂度为O(m+n)。
   例如,设所给的两个序列为X=<A,B,C,B,D,A,B>和Y=<B,D,C,A,B,A>。由算法LCS_LENGTH和LCS计算出的结果如下图所示:

   
   
   我来说明下此图(参考算法导论)。在序列X={A,B,C,B,D,A,B}和 Y={B,D,C,A,B,A}上,由LCS_LENGTH计算出的表c和b。第i行和第j列中的方块包含了c[i,j]的值以及指向b[i,j]的箭头。在c[7,6]的项4,表的右下角为X和Y的一个LCS<B,C,B,A>的长度。对于i,j>0,项c[i,j]仅依赖于是否有xi=yi,及项c[i-1,j]和c[i,j-1]的值,这几个项都在c[i,j]之前计算。为了重构一个LCS的元素,从右下角开始跟踪b[i,j]的箭头即可,这条路径标示为阴影,这条路径上的每一个“↖”对应于一个使xi=yi为一个LCS的成员的项(高亮标示)。

所以根据上述图所示的结果,程序将最终输出:“B C B A”。


0 0