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 }

 

posted @ 2013-08-15 18:28  Naix_x  阅读(253)  评论(0编辑  收藏  举报