不管怎么合并,最后的答案一定是由 a a a串连续的一段和 b b b串连续段一段拼起来的
那么定义 f [ i ] [ i i ] [ j ] [ j j ] f[i][ii][j][jj] f[i][ii][j][jj]为取 a a a串的 [ i , i i ] [i,ii] [i,ii]和 b b b串的 [ j , j j ] [j,jj] [j,jj]是否可能构成回文
那么显然可以通过在两端加字母达成目的
最明显的两种方式
if( l1>=2 ) f[i][ii][j][jj] |= f[i+1][ii-1][j][jj]*( a[i]==a[ii] );
if( l2>=2 ) f[i][ii][j][jj] |= f[i][ii][j+1][jj-1]*( b[j]==b[jj] );
还可以从 a a a串拿一个,从 b b b串拿一个
但是因为是分别在两头
所以需要分别拿左端点和右端点
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <queue>
#include <set>
using namespace std;
int f[59][59][59][59];
char a[59],b[59];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int T; cin >> T;
while( T-- )
{
cin >> (a+1) >> (b+1);
int len1 = strlen(a+1);
int len2 = strlen(b+1);
int ans = 0;
for(int l1=0;l1<=len1;l1++)
for(int l2=0;l2<=len2;l2++)
{
for(int i=1;i+l1-1<=len1;i++)
for(int j=1;j+l2-1<=len2;j++)
{
int ii = i+l1-1;
int jj = j+l2-1;
if( l1+l2<=1 ) f[i][ii][j][jj] = 1;
if( l1&&l2 ) f[i][ii][j][jj] |= f[i+1][ii][j][jj-1]*( a[i]==b[jj] );
if( l1&&l2 ) f[i][ii][j][jj] |= f[i][ii-1][j+1][jj]*( a[ii]==b[j] );
if( l1>=2 ) f[i][ii][j][jj] |= f[i+1][ii-1][j][jj]*( a[i]==a[ii] );
if( l2>=2 ) f[i][ii][j][jj] |= f[i][ii][j+1][jj-1]*( b[j]==b[jj] );
if( f[i][ii][j][jj] ) ans = max( ans,l1+l2 );
}
}
cout << ans << endl;
memset(f,0,sizeof(f));
}
}