题目

涉及的知识点
区间dp: 在区间上进行动态规划,求解一段区间上的最优解。主要是通过合并小区间的最优解从而得出整个大区间上最优解的dp算法。
解题思路
第一步,数据不大,故建四维数组,设dp[l1][r1][l2][r2]表示a[l1…r1]和b[l2…r2]合并是否能组成回文串
第二步,当(r1-l1)+(r2-l2)<=1,dp[l1][r1][l2][r2]=1(即true)
第三步,转移方程:
1 2 3 4 5 6 7 8
| dp[l1][r1][l2][r2] |= dp[l1+1][r1-1][l2][r2];
dp[l1][r1][l2][r2] |= dp[l1][r1][l2+1][r2-1];
dp[l1][r1][l2][r2] |= dp[l1+1][r1][l2][r2-1];
dp[l1][r1][l2][r2] |= dp[l1+1][r1-1][l2+1][r2];
|
ac代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| #include<bits/stdc++.h> using namespace std; typedef long long LL; const double pi=acos(-1),eps=1e-10; const int inf=0x3f3f3f3f; const int mod=1e9+7;
bool dp[55][55][55][55];
int main() { int t; string a,b; cin>>t; while(t--){ memset(dp,0,sizeof(dp)); cin>>a>>b; a=" "+a,b=" "+b; int ans=0; int la=a.length()-1,lb=b.length()-1; for(int len1=0; len1<=la; len1++){ for(int len2=0; len2<=lb; len2++){ for(int l1=1,r1=l1+len1-1; r1<=la; l1++,r1++){ for(int l2=1,r2=l2+len2-1; r2<=lb; l2++,r2++){ if(len1+len2<=1)dp[l1][r1][l2][r2]=1; else{ if(a[l1]==a[r1]&&r1>0)dp[l1][r1][l2][r2]|=dp[l1+1][r1-1][l2][r2]; if(a[l1]==b[r2]&&r2>0)dp[l1][r1][l2][r2]|=dp[l1+1][r1][l2][r2-1]; if(b[l2]==a[r1]&&r1>0)dp[l1][r1][l2][r2]|=dp[l1][r1-1][l2+1][r2]; if(b[l2]==b[r2]&&r2>0)dp[l1][r1][l2][r2]|=dp[l1][r1][l2+1][r2-1]; } if(dp[l1][r1][l2][r2]){ ans=max(ans,r1-l1+r2-l2+2); } }}}} cout<<ans<<endl;
}
return 0; }
|