http://acm.hdu.edu.cn/showproblem.php?pid=4681
枚举A串和B串包含C串的区间 枚举区间端点算左右两端最长公共子序
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<stdlib.h> 5 #include<algorithm> 6 using namespace std; 7 #define N 1010 8 char s1[N],s2[N],s3[N]; 9 int dp1[N][N],dp2[N][N]; 10 struct node 11 { 12 int l,r; 13 }p1[N],p2[N]; 14 int main() 15 { 16 int i,j,t,k1,k2,k3,kk=0; 17 scanf("%d",&t); 18 while(t--) 19 { 20 kk++; 21 memset(dp1,0,sizeof(dp1)); 22 memset(dp2,0,sizeof(dp2)); 23 scanf("%s%s%s",s1,s2,s3); 24 k1 = strlen(s1); 25 k2 = strlen(s2); 26 k3 = strlen(s3); 27 for(i = 1 ; i <= k1 ; i++) 28 for(j = 1; j <= k2 ;j++) 29 { 30 if(s1[i-1]==s2[j-1]) 31 dp1[i][j] = dp1[i-1][j-1]+1; 32 else 33 dp1[i][j] = max(dp1[i-1][j],dp1[i][j-1]); 34 } 35 for(i = k1 ; i>= 1 ; i--) 36 for(j = k2 ; j >= 1 ; j--) 37 { 38 if(s1[i-1]==s2[j-1]) 39 dp2[i][j] = dp2[i+1][j+1]+1; 40 else 41 dp2[i][j] = max(dp2[i+1][j],dp2[i][j+1]); 42 } 43 int g = 0;j=0; 44 for(i = 0 ; i < k1 ; i++) 45 if(s1[i]==s3[j]) 46 { 47 j++;int a=i; 48 if(j<k3) 49 { 50 for(a = i+1 ; a < k1 ; a++) 51 { 52 if(s1[a]==s3[j]) 53 j++; 54 if(j==k3) 55 break; 56 } 57 } 58 if(j==k3) 59 { 60 g++; 61 p1[g].l = i; 62 p1[g].r = a+1; 63 } 64 j = 0; 65 } 66 int o=0;j=0; 67 for(i = 0 ; i < k2 ; i++) 68 if(s2[i]==s3[j]) 69 { 70 j++;int a=i; 71 if(j<k3) 72 { 73 for(a = i+1 ; a < k2 ; a++) 74 { 75 if(s2[a]==s3[j]) 76 j++; 77 if(j==k3) 78 break; 79 } 80 } 81 if(j==k3) 82 { 83 o++; 84 p2[o].l = i; 85 p2[o].r = a+1; 86 } 87 j = 0; 88 } 89 int maxz=0; 90 for(i = 1; i <= g ; i++) 91 for(j = 1 ; j <= o ; j++) 92 { 93 int x = dp1[p1[i].l][p2[j].l],x2 = dp2[p1[i].r+1][p2[j].r+1]; 94 maxz = max(maxz,x+x2); 95 } 96 printf("Case #%d: %d ",kk,maxz+k3); 97 } 98 return 0; 99 }