题意:输入两个字符串A和B,合并成一个串C,属于A和B的字符在C中顺序保持不变。如"abc"和"xyz"可以被组合成"axbycz"或"abxcyz"等。我们定义字符串的价值为其最长回文子串的长度(回文串表示从正反两边看完全一致的字符串,如"aba"和"xyyx")。需要求出所有可能的C中价值最大的字符串,输出这个最大价值即可。
思路:区间dp,dp[i][j][k][s]表示仅考虑a字符串的i-j区间,b字符串的k-s区间的构成回文串的合法性。(注意:不能首首转移,不然就不能保证字符串顺序,java开四维的Int数组真的比boolean数组慢很多,用Int数组会爆时间。也是看了大佬的某篇博客才懂的,orz)。
import java.io.*;
import java.util.Scanner;
public class Main{
public static BufferedReader rd=new BufferedReader(new InputStreamReader(System.in));
public static BufferedWriter wd=new BufferedWriter(new OutputStreamWriter(System.out));
public static Scanner s=new Scanner(System.in);
public static void solve()throws Exception{
String a=rd.readLine(),b=rd.readLine();
// String y=s.next();
int L=a.length(),R=b.length();
boolean dp[][][][]=new boolean [L+10][L+10][R+10][R+10];
int ans=0;
for(int len1=0;len1<=L;len1++) {
for(int len2=0;len2<=R;len2++) {
for(int i=1,j=len1;j<=L;i++,j++) {
for(int k=1,s=len2;s<=R;k++,s++) {
if(len1+len2<=1) dp[i][j][k][s]=true;
else {
if(len1>1&&a.charAt(i-1)==a.charAt(j-1)) {
dp[i][j][k][s]|=dp[i+1][j-1][k][s];
}
if(len2>1&&b.charAt(k-1)==b.charAt(s-1)) {
dp[i][j][k][s]|=dp[i][j][k+1][s-1];
}
if(len1>0&&len2>0&&a.charAt(i-1)==b.charAt(s-1)) {
dp[i][j][k][s]|=dp[i+1][j][k][s-1];
}
if(len1>0&&len2>0&&b.charAt(k-1)==a.charAt(j-1)) {
dp[i][j][k][s]|=dp[i][j-1][k+1][s];
}
}
if(dp[i][j][k][s]) ans=Math.max(ans, len1+len2);
}
}
}
}
wd.write(ans+"\n");
}
public static void main(String fsda[])throws Exception{
int t=Integer.parseInt(rd.readLine());
while(t>0) {
t--;
solve();
wd.flush();
}
}
}