链接:https://ac.nowcoder.com/acm/problem/13230
来源:牛客网
题目描述
输入两个字符串A和B,合并成一个串C,属于A和B的字符在C中顺序保持不变。如"abc"和"xyz"可以被组合成"axbycz"或"abxcyz"等。
我们定义字符串的价值为其最长回文子串的长度(回文串表示从正反两边看完全一致的字符串,如"aba"和"xyyx")。
需要求出所有可能的C中价值最大的字符串,输出这个最大价值即可
输入描述:
第一行一个整数T(T ≤ 50)。
接下来2T行,每两行两个字符串分别代表A,B(|A|,|B| ≤ 50),A,B的字符集为全体小写字母。
输出描述:
对于每组数据输出一行一个整数表示价值最大的C的价值。
输入
2
aa
bb
a
aaaabcaa
输出
4
5
Solution
Code
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N = 5e4 + 5; const ll mod = 998244353; const int DEG = 30; const double pi = acos(-1.0); const double eps = 1e-8; const int inf = 0x3f3f3f3f; static auto faster_iostream = []() { std::ios::sync_with_stdio(false); // turn off sync std::cin.tie(nullptr); // untie in/out streams return 0; }(); bool dp[55][55][55][55]; int main(){ string s, t; int test; cin >> test; while(test--){ memset(dp, 0, sizeof(dp)); cin >> s >> t; s = " " + s, t = " " + t; // 让下标从1开始 方便处理 int ans = 0; int s_len = s.size() - 1, t_len = t.size() - 1; for(int len1 = 0; len1 <= s_len; len1++){ // 枚举 s 串的贡献 for(int len2 = 0; len2 <= t_len; len2++){ // 枚举 t 串的贡献 for(int l1 = 1, r1 = l1 + len1 - 1; r1 <= s_len; r1++, l1++){ // 截取一段 s 中长度为 len1 的子串 for(int l2 = 1, r2 = l2 + len2 - 1; r2 <= t_len; r2++, l2++){ // 截取一段 t 中长度为 len2 的子串 if(len1 + len2 <= 1){ dp[l1][r1][l2][r2] = 1; // 单个字符是回文串 } else { if(s[l1] == s[r1] && r1 > 0){ // 这个 s 的子串的首尾相同 dp[l1][r1][l2][r2] |= dp[l1 + 1][r1 - 1][l2][r2]; // 1.由 l1 + 1 -> r1 - 1 扩展为 l -> r } if(s[l1] == t[r2] && r2 > 0){ dp[l1][r1][l2][r2] |= dp[l1 + 1][r1][l2][r2 - 1]; // 2. 对于当前的串 前面加 s[l1], 后面加 t[r2]; } if(t[l2] == t[r2] && r2 > 0){ dp[l1][r1][l2][r2] |= dp[l1][r1][l2 + 1][r2 - 1]; // 同1 } if(t[l2] == s[r1] && r1 > 0){ dp[l1][r1][l2][r2] |= dp[l1][r1 - 1][l2 + 1][r2]; // 同2 } if(dp[l1][r1][l2][r2]){ ans = max(ans, r1 - l1 + 1 + r2 - l2 + 1); // 如果当前dp[l1][r1][l2][r2] 为true 说明为回文串 更新答案 } } } } } } cout << ans << "\n"; } return 0; }