zoukankan      html  css  js  c++  java
  • 最长公共子序列--动态规划入门

    求两个序列 X{1,2, 5, 4, 。。。}和Y{1, 5, 4,,,,}中最长的共有序列。 例如X = {A,B, C, B,D, A, B}, Y={B,D,C,A,B,A} 两者的最长公共子序列为 {B,C,B, A}

    分析:

    这个问题是否可以分成一段一段处理呢? (即可否找出递归结构, 可见递归很重要, 也许你感觉它很基础,其实它很深奥!)。我们从X,Y的最后一个元素来考虑, 若X的最后一个元素在最长子串中(即它对最长子串有贡献), 那么有两种情况, 它和Y的最后一个元素相同, 或它与Y最后一个对最长子串有贡献的元素相等(你也许会说, 这个SB也知道, 但它偏偏很重要)。 另 c[i][j] 记录从 Xi和Yj的公共最长子序列。(这类题都是他妈的,这一个怂样,不要问我为什么)。

    于是乎, 关键的递归公式横空出世。

                           当 i= 0, 或 j = 0 时, c[i][j ] = 0;

            当i, j>0, xi = yj   时, c[i][j] = c[i-1][j-1] + 1;

                           当i,j>0, xi != yj  时, c[i][j] = {c[i][j-1], c[i-1][j]}  --->就是由那个SB都知道的东西推来的!!嘿嘿!

    #include<iostream>
    #include<cstring>
    using namespace std;
    
    const int maxn = 100+5;
    int b[maxn][maxn];
    char x[maxn], y[maxn];
    //用b[][]来记录取得最优值的路径。 
    int lcsLength(char x[maxn], char y[maxn], int b[maxn][maxn])//计算最优解。 
    {
        int m = x.length - 1;
        int n = y.length - 1;
        int c[m+1][n+1];
        for(int i=1; i<=m; i++) c[i][0] = 0;
        for(int i=1; i<=n; i++) c[0][i] = 0;
        for(int i=1; i<=m; i++)
        for(int j=1; j<=n; j++)
        {
            if(x[i]==y[j])
            {
                c[i][j] = c[i-1][j-1] + 1;
                b[i][j] = 1;                   
            }
            else if(c[i-1][j]>=c[i][j-1])
            {
                c[i][j] = c[i-1][j];
                b[i][j] = 2;
            }
            else
            {
                c[i][j] = c[i][j-1];
                b[i][j] = 3;
            }
        }
        return c[m][n];
    }
    
    //构造最优子序列。
    void lcs(int i, int j, char x[maxn], int b[maxn][maxn])
    {
        if(i==0||j==0) return;
        if(b[i][j]==1)
        {
            lcs(i-1, j-1, x, b);//又是递归, 看到了吧!! 
            printf("%c", x[i]);
        }
        else if(b[i][j]==2) lcs(i-1, j, x, b);
        else lcs(i, j-1, x, b);
    } 
    
    int main()
    {
        /* 读入字符串x,y时从1读*/
    } 

      

  • 相关阅读:
    paper:synthesizable finit state machine design techniques using the new systemverilog 3.0 enhancements之output encoded style with registered outputs(Good style)
    软测(一)
    package.json
    邬江兴:网络安全“再平衡战略”抓手--拟态防御
    什么是DDOS攻击?怎么防御?
    什么是gitlab CI ?CI代表什么?
    结构体字节对齐(转)
    MySQL 及 SQL 注入与防范方法
    HDU 4704 Sum (费马小定理)
    HDU 4704 Sum (费马小定理)
  • 原文地址:https://www.cnblogs.com/acm1314/p/4531999.html
Copyright © 2011-2022 走看看