合并回文子串
链接:https://ac.nowcoder.com/acm/problem/13230
来源:牛客网
题目描述
输入两个字符串A和B,合并成一个串C,属于A和B的字符在C中顺序保持不变。如"abc"和"xyz"可以被组合成"axbycz"或"abxcyz"等。
我们定义字符串的价值为其最长回文子串的长度(回文串表示从正反两边看完全一致的字符串,如"aba"和"xyyx")。
需要求出所有可能的C中价值最大的字符串,输出这个最大价值即可
我们定义字符串的价值为其最长回文子串的长度(回文串表示从正反两边看完全一致的字符串,如"aba"和"xyyx")。
需要求出所有可能的C中价值最大的字符串,输出这个最大价值即可
输入描述:
第一行一个整数T(T ≤ 50)。 接下来2T行,每两行两个字符串分别代表A,B(|A|,|B| ≤ 50),A,B的字符集为全体小写字母。
输出描述:
对于每组数据输出一行一个整数表示价值最大的C的价值。
示例1
输出
复制 4
5
设dp[i][j][k][l],然后将所有会出现的状态枚举出来即:s1[i]=s1[j],s2[k]=s2[l],s1[i]=s2[l],s2[k]=s1[k].4种状态枚举出来后,再将每种可能出现的字符串由小判断到大,即:先从只有s1的字符串,并且只有1个字符,在到2个字符....等一直到s1的最后一个字符,在尝试的把s2里的第一个字符带入,在接着一个一个的列出和判断,从而达到解决子问题联系到父问题,以下治上的效果(本人连续写了好几道动态规划,但大部分还是查了题解才会写,并且将问题分解子问题的要领也没掌握,希望有人能指点一下,O(∩_∩)O哈哈~)
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<iostream> 3 #include<algorithm> 4 #include<memory.h> 5 #include<cmath> 6 using namespace std; 7 bool dp[55][55][55][55]; //dp[i][j][k][l],i和j代表从i到j开始的字符串,k和l代表从k到l开始的字符串 8 int main() 9 { 10 char s1[55], s2[55]; 11 int T; 12 scanf("%d", &T); 13 while (T--) { 14 memset(dp, false, sizeof(dp)); 15 scanf("%s%s", s1 + 1, s2 + 1); 16 int len1 = strlen(s1 + 1); 17 int len2 = strlen(s2 + 1); 18 int ans = 0; 19 for (int d1 = 0; d1 <= len1; d1++) 20 for (int d2 = 0; d2 <= len2; d2++) 21 for (int i = 1,j = d1; j <= len1; j++, i++) 22 for (int k = 1, l = d2; l <= len2; l++, k++) 23 { 24 if (d1 + d2 <= 1) dp[i][j][k][l] = true; 25 else 26 { 27 if (d1&&s1[i] == s1[j]) dp[i][j][k][l] |= dp[i + 1][j - 1][k][l]; 28 if (d2&&s2[k] == s2[l]) dp[i][j][k][l] |= dp[i][j][k + 1][l - 1]; 29 if (d1&&d2&&s1[i] == s2[l]) dp[i][j][k][l] |= dp[i + 1][j][k][l - 1]; 30 if (d1&&d2&&s1[j] == s1[k]) dp[i][j][k][l] |= dp[i][j - 1][k + 1][l]; 31 } 32 if (dp[i][j][k][l]) 33 ans = max(ans, d1+d2); 34 } 35 printf("%d\n", ans); 36 } 37 }