【每日一题】2.合并回文子串 (字符串处理 + 区间DP)

题目链接:Here

遇到这种数据范围较小的计数问题应该优先考虑dp,本题就是如此。
那么应该怎么样考虑转移呢?
首先最后C中的那个价值最大的子串一定是由字符串A的一个区间和字符串B的一个区间合并得到的,
那么现在假设 A[i] ~ A[j]B[k] ~ B[l] 构成了一个回文串(这里设 dp[i][j][k][l])

则他能转移到的区间有
1:\(a[i-1]==a[j+1] 时\ dp[i-1][j+1][k][l]\)
2:\(a[i-1]==b[l+1]时\ dp[i-1][j][k][l+1]\)
3:\(b[k-1]==a[j+1]时\ dp[i][j+1][k-1][l]\)
4:\(b[k-1]==b[l+1]时\ dp[i][j][k-1][l+1]\)

那么对于的转移方程也就是:

if (a[i] == a[j]) dp[i][j][k][l] |= dp[i + 1][j - 1][k][l];
if (b[k] == b[l]) dp[i][j][k][l] |= dp[i][j][k + 1][l - 1];
if (a[i] == b[l]) dp[i][j][k][l] |= dp[i + 1][j][k][l - 1];
if (a[j] == b[k]) dp[i][j][k][l] |= dp[i][j - 1][k + 1][l];

然后就可以轻松的区间转移啦~~~~~
oh,在注意一下枚举过程中只有一个字母的状态一定是回文的就可以啦

AC 代码

// Murabito-B 21/04/06
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int dp[60][60][60][60];
int main() {
    ios_base::sync_with_stdio(false), cin.tie(0);
    int _;
    for (cin >> _; _--;) {
        string a, b;
        cin >> a >> b;
        a = "@" + a, b = "@" + b;
        int lena = a.size(), lenb = b.size();
        int ans = 0;
        for (int l1 = 0; l1 <= lena; ++l1)
            for (int l2 = 0; l2 <= lenb; ++l2)
                for (int i = 1; i <= lena - l1; ++i)
                    for (int k = 1; k <= lenb - l2; ++k) {
                        int j = i + l1 - 1, l = k + l2 - 1;
                        // 说明此时仅一个点
                        if (l1 + l2 <= 1) dp[i][j][k][l] = 1;
                        else {
                            dp[i][j][k][l] = 0;
                            if (a[i] == a[j]) dp[i][j][k][l] |= dp[i + 1][j - 1][k][l];
                            if (b[k] == b[l]) dp[i][j][k][l] |= dp[i][j][k + 1][l - 1];

                            if (a[i] == b[l]) dp[i][j][k][l] |= dp[i + 1][j][k][l - 1];
                            if (a[j] == b[k]) dp[i][j][k][l] |= dp[i][j - 1][k + 1][l];
                        }
                        if (dp[i][j][k][l]) ans = max(ans, l1 + l2);
                    }
        cout << ans << "\n";
    }
    return 0;
}
posted @ 2021-04-06 14:37  RioTian  阅读(121)  评论(0编辑  收藏  举报