HDU 4681 String(DP)
枚举A和B中每一段含有C的段,A的前面 后面和B前面后面,求最长公共子序。观察发现,可以预处理最长公共子序。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 using namespace std; 7 int dp1[1001][1001],dp2[1001][1001]; 8 char s1[1010]; 9 char s2[1010]; 10 char s3[1010]; 11 char s4[1010]; 12 char s5[1010]; 13 int que1[1010][3]; 14 int que2[1010][3]; 15 int main() 16 { 17 int t,cas = 1,i,j,n1,n2,k; 18 int len1,len2,len3; 19 scanf("%d",&t); 20 while(t--) 21 { 22 scanf("%s%s%s",s1,s2,s3); 23 len1 = strlen(s1); 24 len2 = strlen(s2); 25 len3 = strlen(s3); 26 for(i = 0;i <= len1;i ++) 27 { 28 for(j = 0;j <= len2;j ++) 29 { 30 dp1[i][j] = dp2[i][j] = 0; 31 } 32 } 33 for(i = 1;i <= len1;i ++) 34 { 35 for(j = 1;j <= len2;j ++) 36 { 37 if(s1[i-1] == s2[j-1]) 38 dp1[i][j] = dp1[i-1][j-1] + 1; 39 else 40 dp1[i][j] = max(dp1[i-1][j],dp1[i][j-1]); 41 } 42 } 43 for(i = 0;i < len1;i ++) 44 { 45 s4[i] = s1[len1-i-1]; 46 } 47 for(i = 0;i < len2;i ++) 48 { 49 s5[i] = s2[len2-i-1]; 50 } 51 for(i = 1;i <= len1;i ++) 52 { 53 for(j = 1;j <= len2;j ++) 54 { 55 if(s4[i-1] == s5[j-1]) 56 dp2[i][j] = dp2[i-1][j-1] + 1; 57 else 58 dp2[i][j] = max(dp2[i-1][j],dp2[i][j-1]); 59 } 60 } 61 n1 = n2 = 0; 62 for(i = 0;i < len1;i ++) 63 { 64 if(s1[i] == s3[0]) 65 { 66 k = 1; 67 for(j = i+1;j < len1;j ++) 68 { 69 if(s1[j] == s3[k]) 70 k ++; 71 if(k == len3) break; 72 } 73 if(j != len1) 74 { 75 que1[n1][0] = i; 76 que1[n1][1] = j; 77 n1 ++; 78 } 79 } 80 } 81 for(i = 0;i < len2;i ++) 82 { 83 if(s2[i] == s3[0]) 84 { 85 k = 1; 86 for(j = i+1;j < len2;j ++) 87 { 88 if(s2[j] == s3[k]) 89 k ++; 90 if(k == len3) break; 91 } 92 if(j != len2) 93 { 94 que2[n2][0] = i; 95 que2[n2][1] = j; 96 n2 ++; 97 } 98 } 99 } 100 int ans = 0; 101 /*for(i = 1;i <= len1;i ++) 102 { 103 for(j = 1;j <= len2;j ++) 104 { 105 printf("%d ",dp1[i][j]); 106 } 107 printf("\n"); 108 }*/ 109 /*for(i = 0;i < n1;i ++) 110 { 111 printf("%d %d\n",que1[i][0],que1[i][1]); 112 } 113 for(i = 0;i < n2;i ++) 114 { 115 printf("%d %d\n",que2[i][0],que2[i][1]); 116 }*/ 117 for(i = 0;i < n1;i ++) 118 { 119 for(j = 0;j < n2;j ++) 120 { 121 ans = max(ans,dp1[que1[i][0]][que2[j][0]] + dp2[len1-que1[i][1]-1][len2-que2[j][1]-1]); 122 } 123 } 124 printf("Case #%d: %d\n",cas++,ans + len3); 125 } 126 return 0; 127 }