计算a、b字符串的不连续公共子串的长度(包含c字符串) ----hdu4681

来源:互联网 发布:加拿大和中国知乎 编辑:程序博客网 时间:2024/06/08 07:45

题意:

给你字符串A,B,C,让你找一个字符串D,使得D串是A,B的字串,C串是D的连续字串。

做法:

找出C串在A,B串的位置。

对于每一个位置对,D串的长度为前一半的最长公共子序列+C串的长度+后一半的最长公共子序列



#include <iostream>#include <cstdio>#include <cstring>#define N 1005#define Max(a,b) a>b?a:busing namespace std;int len1,len2,len3,num;int dp1[N][N],dp2[N][N],pp[N<<2][2];//dp1[][]表示字符串a,b从前往后的最大公共子串,dp2[][]表示字符串a,b从后往前的最大公共子串//pp[][]记录字符串c在a,b中出现的第一个位置和最后一个位置char a[N],b[N],c[N];void solve(char *str,int n){    int i,j,k;    int l=strlen(str);    for(i=0; i<=l-len3; i++)        if(str[i]==c[0])        {            for(j=i,k=0; j<n&&k<len3; j++)                if(str[j]==c[k])                    k++;            if(k==len3)            {                pp[num][0]=i+1;                pp[num][1]=j;                num++;            }            else break;        }}int main(){    int i,j,T,Count=0;    scanf("%d",&T);    getchar();    while(T--)    {        gets(a);        len1=strlen(a);        gets(b);        len2=strlen(b);        gets(c);        len3=strlen(c);        memset(dp1,0,sizeof(dp1));        for(i=1; i<=len1; i++)            for(j=1; j<=len2; j++)                if(a[i-1]==b[j-1])dp1[i][j]=dp1[i-1][j-1]+1;                else dp1[i][j]=Max(dp1[i-1][j],dp1[i][j-1]);        memset(dp2,0,sizeof(dp2));        for(i=len1; i>=1; i--)            for(j=len2; j>=1; j--)                if(a[i-1]==b[j-1])dp2[i][j]=dp2[i+1][j+1]+1;                else dp2[i][j]=Max(dp2[i+1][j],dp2[i][j+1]);        int x,y;        num=0;        solve(a,len1);        x=num;        solve(b,len2);        y=num-x;        int ans=0;        for(i=0; i<x; i++)            for(j=0; j<y; j++)                ans=Max(ans,dp1[pp[i][0]-1][pp[x+j][0]-1]+dp2[pp[i][1]+1][pp[x+j][1]+1]);        printf("Case #%d: %d\n",++Count,ans+len3);    }    return 0;}


0 0
原创粉丝点击