史题,考虑dp[l1][r1][l2][r2] 维护“考虑了 A 串中从 l1 到 r1 部分,B 串从 l2 到 r2 部分,是否能构成回文串”,然后dp时分类讨论一下转移情况,当更新出新的合法dp值时,直接更新答案即可,时间复杂度 O(n^4)。
#include<bits/stdc++.h> using i64 = long long; bool dp[51][51][51][51]; bool sp[51][51]; bool tp[51][51]; int main() { std::cin.tie(nullptr)->sync_with_stdio(false); int t; std::cin >> t; while (t--) { std::string s, t; std::cin >> s >> t; int ans = 1; int n = s.size(), m = t.size(); memset(dp, 0, sizeof dp); // 两边各取一个拼 for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { dp[i][i][j][j] = (s[i] == t[j]); } } // 预处理回文 for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { sp[i][j] = 1; } } for (int i = 0; i < m; i++) { for (int j = 0; j < m; j++) { tp[i][j] = 1; } } // 暴力处理单独是不是回文串 for (int i = 0; i < n; i++) { for (int j = i; j < n; j++) { bool ok = 1; for (int l = i, r = j; l < r; l++, r--) { ok &= (s[l] == s[r]); } sp[i][j] = ok; if (ok) { ans = std::max(ans, j - i + 1); } } } for (int i = 0; i < m; i++) { for (int j = i; j < m; j++) { bool ok = 1; for (int l = i, r = j; l < r; l++, r--) { ok &= (t[l] == t[r]); } tp[i][j] = ok; if (ok) { ans = std::max(ans, j - i + 1); } } } // 处理一边只取一个字符的回文串 for (int i = 0; i < n; i++) { for (int l2 = 1; l2 <= m; l2++) { for (int j = 0; j + l2 - 1 < m; j++) { dp[i][i][j][j + l2 - 1] |= (s[i] == t[j + l2 - 1] && tp[j][j + l2 - 1 - 1]); dp[i][i][j][j + l2 - 1] |= (s[i] == t[j] && tp[j + 1][j + l2 - 1]); if (l2 == 2) { dp[i][i][j][j + l2 - 1] |= (t[j] == t[j + l2 - 1] && tp[j + 1][j + l2 - 1 - 1]); } if (dp[i][i][j][j + l2 - 1]) { ans = std::max(ans, l2 + 1); } } } } for (int i = 0; i < m; i++) { for (int l1 = 1; l1 <= n; l1++) { for (int j = 0; j + l1 - 1 < n; j++) { dp[j][j + l1 - 1][i][i] |= (t[i] == s[j + l1 - 1] && sp[j][j + l1 - 1 - 1]); dp[j][j + l1 - 1][i][i] |= (t[i] == s[j] && sp[j + 1][j + l1 - 1]); if (l1 == 2) { dp[j][j + l1 - 1][i][i] |= (s[j] == s[j + l1 - 1] && sp[j + 1][j + l1 - 1 - 1]); } if (dp[j][j + l1 - 1][i][i]) { ans = std::max(ans, l1 + 1); } } } } // 主dp部分 for (int l1 = 1; l1 <= n; l1++) { for (int l2 = 1; l2 <= m; l2++) { for (int i = 0; i + l1 - 1 < n; i++) { for (int j = 0; j + l2 - 1 < m; j++) { if (l1 == 2) {// sc + st[] + sc dp[i][i + l1 - 1][j][j + l2 - 1] |= (s[i] == s[i + l1 - 1] && tp[j][j + l2 - 1]); } else if (l1 > 2) { dp[i][i + l1 - 1][j][j + l2 - 1] |= ((s[i] == s[i + l1 - 1]) && dp[i + 1][i + l1 - 1 - 1][j][j + l2 - 1]); } if (l2 == 2) {// tc + st[] + tc dp[i][i + l1 - 1][j][j + l2 - 1] |= (t[j] == t[j + l2 - 1] && sp[i][i + l1 - 1]); } else if (l2 > 2) { dp[i][i + l1 - 1][j][j + l2 - 1] |= ((t[j] == t[j + l2 - 1]) && dp[i][i + l1 - 1][j + 1][j + l2 - 1 - 1]); } if (l1 > 1 && l2 > 1) { // sc + st[] + tc dp[i][i + l1 - 1][j][j + l2 - 1] |= ((s[i] == t[j + l2 - 1]) && dp[i + 1][i + l1 - 1][j][j + l2 - 1 - 1]); // tc + st[] + sc dp[i][i + l1 - 1][j][j + l2 - 1] |= ((t[j] == s[i + l1 - 1]) && dp[i][i + l1 - 1 - 1][j + 1][j + l2 - 1]); } else if (l1 == 1 && l2 >= 4) {// tc + ts[] + tc dp[i][i + l1 - 1][j][j + l2 - 1] |= ((t[j] == t[j + l2 - 1]) && dp[i][i + l1 - 1][j + 1][j + l2 - 1 - 1]); } else if (l2 == 1 && l1 >= 4) {// sc + ts[] + sc dp[i][i + l1 - 1][j][j + l2 - 1] |= ((s[i] == s[i + l1 - 1]) && dp[i + 1][i + l1 - 1 - 1][j][j + l2 - 1]); } if (dp[i][i + l1 - 1][j][j + l2 - 1]) { // if (l1 + l2 == 7) { // std::cout << i << ", " << i + l1 -1 << ", " << j << j + l2 - 1 << "]\n"; // } ans = std::max(ans, l1 + l2); } } } } } std::cout << ans << "\n"; } return 0; }