链接: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;
} 
京公网安备 11010502036488号