zoukankan      html  css  js  c++  java
  • 算法设计15——动态规划,最长公共子序列

    动态规划

    特征一: 主问题的解包含了子问题的解;

    特征二: 子问题出现重叠;

    ## 前缀动态规划:最长公共子序列(LCS)

    •  问题描述:Z是序列X与Y的公共子序列,如果Z是X的子序列也是Y的子序列。
    •  Naive方法:
      • 枚举X的每个子序列Z
      • 检查Z是否为Y的子序列
      • T(n)=O(n2m)
    •  优化子结构:
      • 设X=(x1, ..., xm)、Y=(y1, ..., yn)是两个序列, LCSXY=(z1, ..., zk)是X与Y的LCS,我们有:
      •  如果xm=yn, 则zk=xm=yn, LCSXY = LCSXm-1Yn-1 + <xm=yn>,   LCSXm-1Yn-1是Xm-1和Yn-1的LCS.    (这个就是最有意思的地方,也就是说LCSXY的任何前缀 如LCSXY=(z1, ..., zk-1)必然是Xm-1和Yn-1的LCS(前缀)
      •  如果xm≠yn,且zk≠xm,则LCSXY是Xm-1和Y的LCS,即 LCSXY = LCSXm-1Y
      •  如果xm≠yn,且zk≠yn,则LCSXY是X与Yn-1的LCS,即 LCSXY = LCSXYn-1

        

    • 子问题重叠性

    • 方程:

        

    •  自底向上计算:

        

    • 伪代码

    复制代码
    输入:X = (x1,x2,...,xm),Y = (y1,y2,...yn)
    输出:Z = X与Y的最长公共子序列
    
    C[0:m,0:n]: C[i,j]是Xi与Yj的LCS的长度   B[1:m,1:n]:
    B[i,j]是指针,指向计算C[i,j]时所选择的子问题的优化解所对应的C表的表项
    
    LCS-length(X, Y)
    m←length(X);n←length(Y);
    For i←0 To m Do C[i,0]←0;
    For j←0 To n Do C[0,j]←0;
    For i←1 To m Do
      For j←1 To n Do
        If xi = yj
        Then C[i,j]←C[i-1,j-1]+1;B[i,j]←“↖”;
          Else If C[i-1,j]≥C[i,j-1] Then
                  C[i,j]←C[i-1,j]; B[i,j]←“↑”;
               Else C[i,j]←C[i,j-1]; B[i,j]←“←”;
    Return C and B.
    
    Print-LCS(B, X, i, j)
    IF i=0 or j=0 THEN Return;
    IF B[i, j]=“↖”
    THEN Print-LCS(B, X, i-1, j-1);
        Print xi;
    ELSE If B[i, j]=“↑”
        THEN Print-LCS(B, X, i-1, j);
        ELSE Print-LCS(B, X, i, j-1).
    
    Print-LCS(B, X, length(X), length(Y))
          可打印出X与Y的LCS。
    复制代码
    • 时间复杂度
      • 计算代价的时间:O(mn)
      • 构造最优解的时间:O(m+n)
      • 总时间复杂度为: O(mn)
    • 空间复杂度
      • 使用数组C和B,需要空间O(mn)

    特征一: 主问题的解包含了子问题的解;

     

    特征二: 子问题出现重叠;

  • 相关阅读:
    【HDU5015】233 Matrix
    【POJ3233】Matrix Power Series
    【POJ3070】Fibonacci
    【NOIP模拟】奇怪的字符串
    【NOIP模拟】超级跳棋
    【NOIP模拟】玛雅文字
    【NOIP模拟】距离
    【闲聊】关于本BLOG
    【NOIP模拟】树
    【NOIP模拟】机器人
  • 原文地址:https://www.cnblogs.com/Ian-learning/p/12493134.html
Copyright © 2011-2022 走看看