hdu 4681 string

来源:互联网 发布:c语言书籍推荐 编辑:程序博客网 时间:2024/06/05 19:03

这个题目就是说现在给你三个字符串a,b,c,要求求出一个字符串d要求长度最大,并且要求d是a,b的子串(注意这个子串没要求字符是连续的),然后c必然是d的连续子串。现在求这个长度。注意到无论如何d串中必然有连续子串c,现在只需要知道c在a,b中的开始位置和结束位置(注意,一旦开始位置选定,结束位置的下标要最小),然后枚举这些位置,分别求出最长公共子序列就好了。附带一组数据,abcddc,bcdd,bc.

#include<iostream>#include<string.h>using namespace std;int dp1[1005][1005];int dp2[1005][1005];int s1[1005][2],s2[1005][2];char a[1005],b[1005],c[1005];int maxi(int a,int b){if(a>b)return a;return b;}int main(){int t,count,i,j,len1,len2,len3,k;count=0;cin>>t;while(t--){count=count+1;cin>>a>>b>>c;len1=strlen(a);len2=strlen(b);len3=strlen(c);for(i=0;i<=len1+1;i++)for(j=0;j<=len2+1;j++){dp1[i][j]=0;dp2[i][j]=0;}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]=maxi(dp1[i-1][j],dp1[i][j-1]);}for(i=len1-1;i>=0;i--)for(j=len2-1;j>=0;j--){if(a[i]==b[j])dp2[i][j]=dp2[i+1][j+1]+1;else dp2[i][j]=maxi(dp2[i+1][j],dp2[i][j+1]);}int numa,numb,sum;numa=0;numb=0;for(i=0;i<len1;i++){if(a[i]==c[0]){s1[numa][0]=i;sum=1;k=1;for(j=i+1;j<len1;j++)if(a[j]==c[k]){sum=sum+1;k=k+1;if(k>=len3)break;}if(sum==len3){s1[numa][1]=j;numa+=1;}}}for(i=0;i<len2;i++){if(b[i]==c[0]){s2[numb][0]=i;sum=1;k=1;for(j=i+1;j<len2;j++)if(b[j]==c[k]){sum=sum+1;k=k+1;if(k>=len3)break;}if(sum==len3){s2[numb][1]=j;numb+=1;}}}int ans=0;/*cout<<s1[0][0]<<" "<<s1[0][1]<<endl;cout<<s2[0][0]<<" "<<s2[0][1]<<endl;cout<<numa<<" "<<numb<<endl;*//*cout<<dp2[3][2]<<endl;*/for(i=0;i<numa;i++)for(j=0;j<numb;j++)ans=maxi(ans,dp1[s1[i][0]][s2[j][0]]+len3+dp2[s1[i][1]+1][s2[j][1]+1]);cout<<"Case #"<<count<<": "<<ans<<endl;}return 0;}


原创粉丝点击