zoukankan      html  css  js  c++  java
  • 最长公共子序列(DP)(二种数组实现+扩展)

    杭电Common Subsequence(1159):

    题意:

    求两个字符串的最大公共子串。

    Sample:

    abcfbc abfcab

    programming contest

    abcd mnp

    4

    2

    0

    代码:

    #include<iostream>

    #include<string.h>

    using namespace std;

     

    const int MAX = 1000 + 10;

     

    char a[MAX];

    char b[MAX];

    int DP[MAX][MAX];

    int Max(int x, int y){               //求最大值

        return x > y ? x : y;

    }

     

    int main(){

        while(cin>>a>>b){

            int len1 = strlen(a);

            int len2 = strlen(b);

            memset(DP,0,sizeof(DP));                    //初始为0,dp问题必备

             // DP[i][j]表示s1前i个字符与s2的前i个字符的最长公共字串长度

            for(int i=1; i<=len1; i++){

                for(int j=1; j<=len2; j++){ 

                    if(a[i-1] == b[j-1])

                        DP[i][j] = DP[i-1][j-1]+1;         //相等时最大长度加1

                    else

                        DP[i][j] = Max(DP[i-1][j], DP[i][j-1]);   //不相等时取前面的最大值

                }

            }

            cout<<DP[len1][len2]<<endl;

        }

        return 0;

    }

    滚动数组Common Subsequence

    #include<iostream>

    #include<string.h>

    using namespace std;

     

    const int maxn = 1000 + 10;

     

    int Max (int a, int b){

         return a > b ? a : b;

    }

     

    char a[maxn];

    char b[maxn];

    int DP[2][maxn];        //相当用两行的的一维数组,因为每次dp的转换只以前一行相关,所以其它的行可以重新用

     

    int main(){

        while(cin>>a>>b){

            int len1 = strlen (a);

            int len2 = strlen (b);

            memset(DP, 0, sizeof(DP));

            for(int i=1; i<=len1; i++){

                for(int j=0; j<=len2; j++){

                    if(a[i-1]==b[j-1])

                    DP[i%2][j]=DP[(i-1)%2][j-1]+1;

                else

                    DP[i%2][j]=Max(DP[(i-1)%2][j],DP[i%2][j-1]);

                }

            }

            cout<<DP[len1%2][len2]<<endl;

        }

        return 0;

    }

    (扩展)用公共子串求最大回文串:

    #include<iostream>

    #include<string.h>

    using namespace std;

     

    const int maxn = 5000 +10;

    int dp[2][maxn];

     

    int Max(int a, int b){

        return a > b ? a : b;

    }

     

    int main(){

        int n;

        while(cin>>n){

            getchar();

            char s1[maxn];

            char s2[maxn];

            gets(s1);

            int len1 = strlen(s1);

            for(int i=0; i<len1; i++){

                s2[len1 - i - 1] = s1[i];

            }

            memset (dp, 0, sizeof(dp));

            for(int i=1;i<=n;i++){

                for(int j=0;j<=n;j++){

                    if(s1[i-1]==s2[j-1]){

                        dp[i%2][j]=dp[(i-1)%2][j-1]+1;

                    }

                    else{

                        dp[i%2][j]=Max(dp[(i-1)%2][j],dp[i%2][j-1]);

                    }

                }

            }

            //cout<<dp[n%2][n]<<endl;

            cout<<n - dp[n%2][n]<<endl;        //总长度减去最大回文串的值就为最大公共串值

        }

        return 0;

    }

  • 相关阅读:
    磁盘上没有足够的空间完成此操作的解决办法_Windows小知识
    使用XAMPP和DVWA在Windows7上搭建渗透测试环境
    使用WampServer和DVWA在Windows10上搭建渗透测试环境
    DOS系统常用命令
    Kali Linux图形界面与命令行界面的切换
    SQLMap入门之在Windows上安装SQLMap
    在Windows下同时安装Python2.x和Python3.x
    Python基础之Windows下Python3.x环境搭建
    在Linux上使用PGP签名验证文件完整性
    Ubuntu软件中心的完全启用
  • 原文地址:https://www.cnblogs.com/cbyniypeu/p/3379877.html
Copyright © 2011-2022 走看看