zoukankan      html  css  js  c++  java
  • LIS 最长上升子序列 LCS 最长公共子序列 模板

    首先介绍一下什么是最长上升子序列   举一个例子  2 1 5 3 6 4 8 9  最长上身子序列是  1 3 4 8 9(不连续)

    #include <iostream>
    #include <algorithm>
    using namespace std;
    int a[1001],ans[1001],len;
    int main()
    {
        int n,T;
        cin>>T;
        while(T--)
        {
            cin>>n;
            for(int i=1;i<=n;i++)
                cin>>a[i];
            ans[1]=a[1];
            len=1;
            for(int i=2;i<=n;i++)
            {
                if(a[i]>ans[len])
                    ans[++len]=a[i];
                else
                {
                    int pos=lower_bound(ans,ans+len,a[i])-ans;
                    ans[pos]=a[i];
                }
            }
            cout<<len<<endl;
        }
        return 0;
    }

    LCS  最长公共子序列

    <1>动态规划

    eg:

    abcfbc abfcab
    programming contest 
    abcd mnp

    Output

    4
    2
    0
    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    ll dp[1001][1001];
    char str1[1111],str2[1111];
    int main()
    {
        while(~scanf("%s%s",str1+1,str2+1))
        {
            str1[0]='.';
            str2[0]='.';
            ll len1=strlen(str1);
            ll len2=strlen(str2);
            memset(dp,0,sizeof(dp));
            for(ll i=1; i<len1; i++)
            {
                for(ll j=1; j<len2; j++)
                {
                    if(str1[i]==str2[j])
                        dp[i][j]=dp[i-1][j-1]+1;
                    else
                        dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
                }
            }
            printf("%lld
    ",dp[len1-1][len2-1]);
        }
        return 0;
    }

    <2>递归方法(最好不用):

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    ll dp[1001][1001];
    string str1,str2;
    ll dfs(ll i,ll j)
    {
        if(!i||!j)
            dp[i][j]=0;
        else
        {
            if(str1[i-1]==str2[j-1])
                dp[i][j]=dfs(i-1,j-1)+1;
            else
                dp[i][j]=max(dfs(i-1,j),dfs(i,j-1));
        }
        return dp[i][j];
    }
    void BUILD_LCS(ll i,ll j)
    {
        if(!i||!j)
            return ;
        if(str1[i-1]==str2[j-1])
        {
            BUILD_LCS(i-1,j-1);
            cout<<str1[i-1];
        }
        else
        {
            if(dp[i-1][j]>dp[i][j-1])
                BUILD_LCS(i-1,j);
    
            else
                BUILD_LCS(i,j-1);
        }
    }
    int main()
    {
        cin>>str1>>str2;
        ll len1=str1.size();
        ll len2=str2.size();
        int ans=dfs(len1,len2);
       // cout<<ans<<endl;
        BUILD_LCS(len1,len2);
        return 0;
    }
    

    例题:

    给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的)。

    比如两个串为:

    abcicba

    abdkscab

    ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列。

    Input

    第1行:字符串A
    第2行:字符串B
    (A,B的长度 <= 1000)

    Output

    输出最长的子序列,如果有多个,随意输出1个。

    Sample Input

    abcicba
    abdkscab

    Sample Output

    abca
    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    ll dp[1001][1001]={0};
    char str1[1111],str2[1111];
    void BUILD_LCS(ll i,ll j)
    {
        if(!i||!j)
            return ;
        if(str1[i]==str2[j])
        {
            BUILD_LCS(i-1,j-1);
            cout<<str1[i];
        }
        else
        {
            if(dp[i-1][j]>dp[i][j-1])
                BUILD_LCS(i-1,j);
            else
                BUILD_LCS(i,j-1);
        }
        return;
    }
    int main()
    {
        scanf("%s%s",str1+1,str2+1);
        memset(dp,0,sizeof(dp));
        str1[0]='.';
        str2[0]='*';
        ll len1=strlen(str1);
        ll len2=strlen(str2);
        for(int i=1;i<len1;i++)
        {
            for(int j=1;j<len2;j++)
            {
                if(str1[i]==str2[j])
                    dp[i][j]=dp[i-1][j-1]+1;
                else
                    dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
            }
        }
        //printf("%lld
    ",dp[len1-1][len2-1]);
        BUILD_LCS(len1-1,len2-1);
        return 0;
    }
    
  • 相关阅读:
    Single Number II
    Pascal's Triangle
    Remove Duplicates from Sorted Array
    Populating Next Right Pointers in Each Node
    Minimum Depth of Binary Tree
    Unique Paths
    Sort Colors
    Swap Nodes in Pairs
    Merge Two Sorted Lists
    Climbing Stairs
  • 原文地址:https://www.cnblogs.com/zcy19990813/p/9702741.html
Copyright © 2011-2022 走看看