本篇先讲述:动态规划求解最长回文字符串长度
令f[i][j]:表示s[i]至s[j]所表示的子串是否为回文串,是为1,否为0.
根据s[i]和s[j]是否相等划分子集
1.s[i]==s[j],那么只要s[i+1]至s[j-1]是回文子串,那么s[i]至s[j]一定是回文子串。如果s[i+1]至s[j-1]不是回文子串,那么s[i]至s[j]也一定不是回文子串
2.s[i]!=s[j] 那么s[i]至s[j]一定不是回文子串
状态方程:
再回到本题,因为本题是2个字符串。所以我们把二维扩展到四维
f[sa][ea][sb][eb]:表示a的sa ~ ea 和 b的sb ~ eb可以构成回文子串的最大长度
转移方程:
if(a[sa]==a[ea]) f[sa][ea][sb][eb]|=f[sa+1][ea-1][sb][eb];
if(b[sb]==b[eb]) f[sa][ea][sb][eb]|=f[sa][ea][sb+1][eb-1];
if(a[sa]==b[eb]) f[sa][ea][sb][eb]|=f[sa+1][ea][sb][eb-1];
if(a[ea]==b[sb]) f[sa][ea][sb][eb]|=f[sa][ea-1][sb+1][eb];
#include<bits/stdc++.h>
using namespace std;
const int N=55;
int f[N][N][N][N];
int t;
char a[N],b[N];
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%s %s",(a+1),(b+1));
int ans=-1;
int lena=strlen(a+1);
int lenb=strlen(b+1);
for(int la=0;la<=lena;la++) //枚举a串的长度
for(int lb=0;lb<=lenb;lb++)//枚举b串的长度
{
for(int sa=1;sa+la-1<=lena;sa++) //枚举a串起点
{
for(int sb=1;sb+lb-1<=lenb;sb++)//枚举b串起点
{
int ea=sa+la-1;int eb=sb+lb-1;//a,b串终点
if(la+lb<=1) f[sa][ea][sb][eb]=1;//长度为1的串,初始化为1
else
{
f[sa][ea][sb][eb]=0;
if(a[sa]==a[ea]) f[sa][ea][sb][eb]|=f[sa+1][ea-1][sb][eb];
if(b[sb]==b[eb]) f[sa][ea][sb][eb]|=f[sa][ea][sb+1][eb-1];
if(a[sa]==b[eb]) f[sa][ea][sb][eb]|=f[sa+1][ea][sb][eb-1];
if(a[ea]==b[sb]) f[sa][ea][sb][eb]|=f[sa][ea-1][sb+1][eb];
}
//1表示是回文串,所以取长度la+lb
if(f[sa][ea][sb][eb]) ans=max(ans,la+lb);
}
}
}
cout<<ans<<endl;
}
}