链接: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 }