Sample Input
2 aaaaa aaaa aa abcdef acebdf cf
Sample Output
Case #1: 4 Case #2: 3题意: 有三个字符串A, B, C。 求串D。D是A, B的公共子序列。C是D的子串。求最长的D串.输出长度.dp[i][j] 表示 A的前i-1, B-1的前j的最长公共子序列。dp1[i][j] 表示 A的后i+1, B+1的后j的最长公共子序列。假设C在A, B中匹配的头尾位置是 ai, aj, bi, bj;ans = max(ans, dp[ai ][bi] + dp1[aj ][bj ] + strlen(C) );暴力求出 C与A, B的所有匹配的 ai, aj, ai, bj这里要预处理出 dp .#include<stdio.h> #include<algorithm> using namespace std; #include<string.h> #define N 1005 char a[N]; char b[N]; char c[N]; int tsa[N]; int tea[N]; int tsb[N]; int teb[N]; struct node { int s; int e; } ansa[N],ansb[N]; int dp1[N][N],dp2[N][N]; int la,lb,lc; char transa[N],transb[N]; void LCS() { memset(dp1,0,sizeof(dp1)); for(int i=1; i<=la; i++) { for(int j=1; j<=lb; 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)); int j=0; for(int i=la-1;i>=0;i--) transa[j++]=a[i]; j=0; for(int i=lb-1;i>=0;i--) transb[j++]=b[i]; for(int i=1; i<=la; i++) { //printf("aa.e=%d %d\n",aa.e,la); for(int j=1; j<=lb; j++) { if(transa[i-1]==transb[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 main() { int t,cas=0; scanf("%d",&t); while(t--) { cas++; int maxx=-999999; memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); scanf("%s%s%s",a,b,c); lc=strlen(c); la=strlen(a); lb=strlen(b); int ta=0,tb=0,k; for(int i=0;i<la;i++) { if(a[i]==c[0]) { k=1; int flag=0; for(int j=i+1;j<la;j++) { if(a[j]==c[k]) k++; if(k==lc) { flag=j; break; } } if(flag!=0) { ansa[ta].s=i; //枚举c串在a串的首尾位子 ansa[ta++].e=flag; } } } for(int i=0;i<lb;i++) { if(b[i]==c[0]) { k=1; int flag=0; for(int j=i+1;j<lb;j++) { if(b[j]==c[k]) k++; if(k==lc) { flag=j; break; } } if(flag!=0) { ansb[tb].s=i; ansb[tb++].e=flag; } } } LCS(); for(int i=0; i<ta; i++) { for(int j=0; j<tb; j++) { //printf("**%d %d %d %d\n",ansa[i].s,ansa[i].e,ansb[j].s,ansb[j].e); //DP(ansa[i],ansb[j]); maxx=max(maxx,dp1[ansa[i].s][ansb[j].s]+dp2[la-1-ansa[i].e][lb-1-ansb[j].e]); } } printf("Case #%d: %d\n",cas,maxx+lc); } return 0; }