原题链接:
https://ac.nowcoder.com/acm/problem/13230
题目大意:
给定两个字符串,不改变两个字符串字符的顺序进行组合,得到一个新字符串,求新字符串中最长的回文子串的长度。
解题思路:
建立一个四维dp数组,该数组是用来判断取组成的字符串是否能构成回文子串。在判断时首尾可以有四种取法:
。判断时先判断首尾字符是否相等,在判断去除首尾后的字符串是否能构成回文串。如
,首尾分别为
,先判断
是否等于
,如果等于在判断,
是否为
,如果为1,那么
。(想不出有什么简单的初始化方法,所以代码中,初始化复杂,并且含有各种特殊情况的特判)。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,a,b) for(i=a;i<=b;i++)
#define debug(a) cout<<#a<<":"<<a<<endl;
const int INF=1e9+7;
const int N=1e6+7;
const int mod=1e9+7;
int maxn,minn;
int T,n;
char a[N],b[N];
int dp[55][55][55][55];
int main(){
int len1,len2;
cin>>T;
while(T--){
memset(dp,0,sizeof(dp));
maxn=0;
scanf("%s%s",a+1,b+1);
len1=strlen(a+1);
len2=strlen(b+1);
for(int i=len1;i>=1;i--){ //只在a字符串中找回文子串
for(int j=i;j<=len1;j++){
if(i==j){
dp[i][j][0][0]=1;
}
else if(i==j-1){
if(a[i]==a[j]){
dp[i][j][0][0]=1;
}
}
else{
if(a[i]==a[j]&&dp[i+1][j-1][0][0]){
dp[i][j][0][0]=1;
}
}
maxn=max(maxn,dp[i][j][0][0]);
}
}
for(int i=len2;i>=1;i--){ //只在b字符串找回文子串
for(int j=i;j<=len2;j++){
if(i==j){
dp[0][0][i][j]=1;
}
else if(i==j-1){
if(b[i]==b[j]){
dp[0][0][i][j]=1;
}
}
else{
if(b[i]==b[j]&&dp[0][0][i+1][j-1]){
dp[0][0][i][j]=1;
}
}
maxn=max(maxn,dp[0][0][i][j]);
}
}
for(int i=len1;i>=1;i--){ //i的顺序要从大到小,因为算dp[i]需要用到dp[i+1],下面同理
for(int j=i;j<=len1;j++){
for(int k=len2;k>=1;k--){
for(int l=k;l<=len2;l++){
if(i!=j){ //当i==j时就无法构成i,k,l,j这种形式
if(i==j-1){
if(a[i]==a[j]&&dp[0][0][k][l]){
dp[i][j][k][l]=1;
}
}
else{
if(a[i]==a[j]&&dp[i+1][j-1][k][l]){
dp[i][j][k][l]=1;
}
}
}
if(k!=l){ //当k==l时就无法构成k,i,j,l这种形式
if(k==l-1){
if(b[k]==b[l]&&dp[i][j][0][0]){
dp[i][j][k][l]=1;
}
}
else{
if(b[k]==b[l]&&dp[i][j][k+1][l-1]){
dp[i][j][k][l]=1;
}
}
}
//接下来是判断能否构成i,j,k,l与k,l,i,j这两种形式
if(i==j&&k==l){
if(a[i]==b[k]){
dp[i][j][k][l]=1;
}
}
if(i==j&&k!=l){
if(a[i]==b[l]&&dp[0][0][k][l-1]){
dp[i][j][k][l]=1;
}
if(a[i]==b[k]&&dp[0][0][k+1][l]){
dp[i][j][k][l]=1;
}
}
if(i!=j&&k==l){
if(a[i]==b[l]&&dp[i+1][j][0][0]){
dp[i][j][k][l]=1;
}
if(a[j]==b[l]&&dp[i][j-1][0][0]){
dp[i][j][k][l]=1;
}
}
if(i!=j&&k!=l){
if(a[i]==b[l]&&dp[i+1][j][k][l-1]){
dp[i][j][k][l]=1;
}
if(b[k]==a[j]&&dp[i][j-1][k+1][l]){
dp[i][j][k][l]=1;
}
}
if(dp[i][j][k][l]==1){
maxn=max(maxn,j-i+1+l-k+1);
}
}
}
}
}
cout<<maxn<<endl;
}
return 0;
} 
京公网安备 11010502036488号