zoukankan      html  css  js  c++  java
  • 51nod 1006 最长公共子序列Lcs 【LCS/打印path】

    基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
     收藏
     关注
    给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的)。
     
    比如两个串为:
     
    abcicba
    abdkscab
     
    ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列。
    Input
    第1行:字符串A
    第2行:字符串B
    (A,B的长度 <= 1000)
    Output
    输出最长的子序列,如果有多个,随意输出1个。
    Input示例
    abcicba
    abdkscab
    Output示例
    abca
    【代码】:
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<iostream>
    #define maxn 1005
    #define maxm 10005
    #define INF 0x3f3f3f3f
    #define LL long long
    using namespace std;
    
    int n,m,t;
    char a[maxn],b[maxn];
    int c[maxn][maxn];
    int dp[maxn][maxn];
    
    
    void LCS(int n, int m)
    {
       for(int i=1; i<=n; i++){
        for(int j=1; j<=m; j++){
            if(a[i-1] == b[j-1]){
                dp[i][j] = dp[i-1][j-1]+1;
                c[i][j] = 1;
            }
            else if(dp[i-1][j] > dp[i][j-1]){
                dp[i][j] = dp[i-1][j];
                c[i][j] = 2;
            }
            else{
                dp[i][j] = dp[i][j-1];
                c[i][j] = 3;
            }
        }
       }
    }
    
    
    void dfs(int i,int j)
    {
        if(!i||!j) return ;
        if(c[i][j]==1){
            dfs(i-1,j-1);
            printf("%c",a[i-1]);
        }
        else if(c[i][j]==2)
            dfs(i-1,j);
        else
            dfs(i,j-1);
    }
    
    int main()
    {
        cin>>a>>b;
    
        memset(c,0,sizeof(c));
        memset(dp,0,sizeof(dp));
    
        n=strlen(a);
        m=strlen(b);
    
        LCS(n,m);
        dfs(n,m);
        cout<<endl;
        return 0;
    }
    1~n : 递归打印
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<iostream>
    #define maxn 1005
    #define maxm 10005
    #define INF 0x3f3f3f3f
    #define LL long long
    using namespace std;
    
    int i,j;
    char a[maxn];
    char b[maxn];
    int dp[maxn][maxn];
    
    void LCS(int n, int m)
    {
        for(int i=1; i<=n; i++){
            for(int j=1; j<=m; j++){
                if(a[i-1] == b[j-1])
                    dp[i][j] = dp[i-1][j-1]+1;
    
                else if(dp[i][j-1] > dp[i-1][j])
                    dp[i][j] = dp[i][j-1];
                else
                    dp[i][j] = dp[i-1][j];
          }
       }
    }
    
    
    int main()
    {
        scanf("%s%s",a,b);
    
        int n=strlen(a);
        int m=strlen(b);
    
        LCS(n,m);
    
        int i=n;
        int j=m;
        int k=dp[i][j]; //倒着来
        char path[maxn]={''}; //逆序
        while(i && j)
        {
            if(a[i-1] == b[j-1] && dp[i][j] == dp[i-1][j-1]+1)
            {
                path[--k]=a[i-1];//逆序
                i--;
                j--;
            }
            else if(a[i-1]!=b[j-1]  && dp[i-1][j] > dp[i][j-1])
                 i--;
            else j--;
        }
        printf("%s
    ",path);
        return 0;
    }
    1~n : 循环打印
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<iostream>
    #include<stack>
    #define maxn 1005
    #define maxm 10005
    #define INF 0x3f3f3f3f
    #define LL long long
    using namespace std;
    
    int i,j;
    char a[maxn];
    char b[maxn];
    int dp[maxn][maxn];
    
    //void LCS(int n, int m)
    //{
    //    for(int i=1; i<=n; i++){
    //        for(int j=1; j<=m; j++){
    //            if(a[i-1] == b[j-1])
    //                dp[i][j] = dp[i-1][j-1]+1;
    //
    //            else if(dp[i][j-1] > dp[i-1][j])
    //                dp[i][j] = dp[i][j-1];
    //            else
    //                dp[i][j] = dp[i-1][j];
    //      }
    //   }
    //}
    
    
    int main()
    {
        scanf("%s%s",a,b);
        int n=strlen(a);
        int m=strlen(b);
        memset(dp,0,sizeof(dp));
    
        for(int i=1; i<=n; i++){
            for(int j=1; j<=m; j++){
                if(a[i-1] == b[j-1])
                    dp[i][j] = dp[i-1][j-1]+1;
                else
                    dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
          }
       }
        int i=n;
        int j=m;
        int k=dp[i][j];
        stack<char> s;
        while(k)
        {
            if(a[i-1] == b[j-1]){
                s.push(a[i-1]);
                i--,j--;
                k--;
            }
            else{
                if(dp[i][j] == dp[i-1][j]) i--;
                else j--;
            }
        }
        while(!s.empty())
        {
            cout<<s.top();
            s.pop();
        }
        return 0;
    }
    /*
    abcicba
    abdkscab
    */
    1~n :栈打印
  • 相关阅读:
    String StringBuffer StringBuilder 之间的区别
    StringBuffer和String的相互转换
    StringBuffer的替换和反转和截取功能
    StringBuffer的添加与删除功能
    后端——框架——容器框架——spring_core——容器
    后端——框架——容器框架——spring_core——bean以及xml配置
    后端——框架——容器框架——spring_core——注解
    后端——框架——容器框架——spring_core——国际化 & Properties
    后端——框架——容器框架——spring_core——Resource
    后端——框架——容器框架——spring_core——校验器
  • 原文地址:https://www.cnblogs.com/Roni-i/p/8921591.html
Copyright © 2011-2022 走看看