HDU2205 又见回文(区间DP)

题意:给定两个字符串(可能为空串),求这两个串交叉组成新串的子串中的回文串的最大长度。

布尔型变量dp[i][j][k][l]表示串a从i到j,b从k到l能否组成新串,初始化为false,则采取区间动态规划。(从1计数)


  1 #include<algorithm>

 2 #include<cmath>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<iostream>
 7 #include<map>
 8 #include<queue>
 9 #include<string>
10 #include<vector>
11 typedef long long LL;
12 using namespace std;
13 
14 char a[100], b[100];
15 const int N = 1008, INF = 0x3F3F3F3F;
16 bool dp[52][52][52][52];
17 
18 int main(){
19     while(gets(a + 1) && gets(b + 1)){
20         int la = strlen(a + 1);
21         int lb = strlen(b + 1);
22         memset(dp, 0sizeof(dp));
23 
24         for(int i = 1; i <= la + 1; i++){
25             for (int j = 1; j <= lb + 1; j++){
26                 dp[i][i][j][j - 1] = dp[i][i - 1][j][j] = dp[i][i - 1][j][j - 1] = 1;
27             }
28         }
29 
30         int ans = 0;
31         for(int l1 = 0; l1 <= la; l1++){
32             for(int l2 = 0; l2 <= lb; l2++){
33                 for(int i = 1, j = i + l1 - 1; j <= la; i++, j++){
34                     for(int k = 1, l = k + l2 - 1; l <= lb; k++, l++){
35                         if(!dp[i][j][k][l]){
36                         bool b1 = i <= j && a[i] == a[j] && dp[i + 1][j - 1][k][l];
37                         bool b2 = k <= l && b[k] == b[l] && dp[i][j][k + 1][l - 1];
38                         bool b3 = l > 0 && a[i] == b[l] && dp[i + 1][j][k][l - 1];
39                         bool b4 = j > 0 && b[k] == a[j] && dp[i][j - 1][k + 1][l];
40                         dp[i][j][k][l] = b1 || b2 ||b3 ||b4;
41                         }
42                         if(dp[i][j][k][l]  && l1 + l2 > ans){
43                             ans = l1 + l2;
44                         }
45                     }
46                 }
47             }
48         }
49         printf("%d ", ans);
50     }
51     return 0;
52 }
原文地址:https://www.cnblogs.com/IMGavin/p/5643105.html