涉及知识点:

区间dp

solution:

划重点:区间dp就是在区间上进行动态规划,求解一段区间上的最优解。主要是通过合并小区间的 最优解进而得出整个大区间上最优解的dp算法。

大多数区间dp的模板都长这样子:

for(int len = 1; len <= n; len++){
    for(int j =1; j + len <= n+1; j++){
        int ends = j + len - 1;
        for(int i = j; i < ends; i++){
            dp[j][lens] = min(dp[j][lens] , dp[j][i] + dp[i+1][ends] + something);
        }
    }
}

接下来分三步求解这道题目:

  • 第一步,设dp[i][j][k][z]表示a[i....j]和b[k.....z]合并是否能组成回文串
  • 第二步,处理初始化,显然当(j-i) + (z-k) 小于等于1,dp[i][j][k][z] = 1
  • 第三步,转移方程:
    //回文串最左边的字符a[i]和最右边的字符a[j]相等
    dp[i][j][k][z] |= dp[i+1][j-1][k][z];
    //回文串最左边的字符b[k]和最右边的字符b[z]相等
    dp[i][j][k][z] |= dp[i][j][k+1][z-1];
    //回文串最左边的字符a[i]和最右边的字符b[z]相等
    dp[i][j][k][z] |= dp[i+1][j][k][z-1];
    //回文串最左边的字符b[k]和最右边的字符a[j]相等
    dp[i][j][k][z] |= dp[i][j-1][k+1][z];

std:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 55;
int dp[maxn][maxn][maxn][maxn];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        string a,b;
        cin>>a>>b;
        int ans = 0;
        for(int l1=0;l1<=a.length();l1++){
            for(int l2=0;l2<=b.length();l2++){
                for(int i=1,j=l1;j<=a.length();i++,j++){
                    for(int k=1,z=l2;z<=b.length();k++,z++){
                        if(l1 + l2 <= 1)
                            dp[i][j][k][z] = 1;
                        else{
                            dp[i][j][k][z] = 0;
                            if(a[i-1] == a[j-1] && l1 > 1)
                                dp[i][j][k][z] |= dp[i+1][j-1][k][z];
                            if(b[k-1] == b[z-1] && l2 > 1)
                                dp[i][j][k][z] |= dp[i][j][k+1][z-1];
                            if(a[i-1] == b[z-1] && l1 && l2)
                                dp[i][j][k][z] |= dp[i+1][j][k][z-1];
                            if(a[j-1] == b[k-1] && l1 && l2)
                                dp[i][j][k][z] |= dp[i][j-1][k+1][z];
                        }
                        if(dp[i][j][k][z])
                            ans = max(ans , l1 + l2);
                    }
                }
            }
        }
        cout<<ans<<endl;
    }
    return  0;
}