牛客传送门

不管怎么合并,最后的答案一定是由 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));
	}
}