合并回文子串

readme

题意:输入两个字符串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();
    	 }
     }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值