原题链接:
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; }