牛客 - 合并回文子串
作者:互联网
题意:输入两个字符串a和b,要求将其合并成字符串c,同时保持a和b中字符顺序不变,求能合成的最长回文子串长度。
分析:区间dp,具体看代码注解。
题解:
#include <bits/stdc++.h> using namespace std; const int N=55; bool dp[N][N][N][N];//意思是a字符串的i到j和b字符串的k到l是否能组成回文子串 char a[N],b[N]; //因为回文串是左右状态相等,所以判断最左和最右的关系即可 //最左和最右的可能性只有:都为a串,都为b串,左边为a右边为b,左边为b右边为a //因为相对位置不变,所以可以分开判断a串和b串的最左最右字符关系 int main() { int t; cin>>t; while(t--) { scanf("%s%s",a+1,b+1); int lena=strlen(a+1),lenb=strlen(b+1); int ans=1; memset(dp,0,sizeof dp); for(int i=0;i<=lena;i++)//枚举a字符串的长度 { for(int j=0;j<=lenb;j++)//枚举b的长度 { for(int sta=1,eda=sta+i-1;eda<=lena;sta++,eda++) {//遍历选中的a字符串区间 for(int stb=1,edb=stb+j-1;edb<=lenb;stb++,edb++) {//遍历选中的b字符串区间 //处理边界情况 if(i+j<=1) dp[sta][eda][stb][edb]=1; else { //两边都是a if(a[sta]==a[eda]&&(eda>0)) dp[sta][eda][stb][edb]|=dp[sta+1][eda-1][stb][edb]; //两边都是b if(b[stb]==b[edb]&&(edb>0)) dp[sta][eda][stb][edb]|=dp[sta][eda][stb+1][edb-1]; //左边是a,右边是b if(a[sta]==b[edb]&&(edb>0)) dp[sta][eda][stb][edb]|=dp[sta+1][eda][stb][edb-1]; //左边是b,右边是a if(b[stb]==a[eda]&&(eda>0)) dp[sta][eda][stb][edb]|=dp[sta][eda-1][stb+1][edb]; } if(dp[sta][eda][stb][edb]) ans=max(ans,i+j); } } } } cout<<ans<<endl; } return 0; }
(如有错误,欢迎礼貌指正。如有疑问,欢迎友好交流。鄙人愚笨,敬请原谅。)
标签:子串,edb,eda,sta,stb,int,牛客,dp,回文 来源: https://www.cnblogs.com/atomsh/p/15184014.html