合併迴文子串
阿新 • • 發佈:2021-01-18
題目連結:點這裡
題解:這個是區間dp,這是我第一次碰到這種四維的,一上來把我搞傻了,看了看大佬的題解才搞明白這道題,下面談談我的理解。
狀態標識:dp[i,j][k,n],i j表示的是第一個字串的迴文,k n表示的是第二個字串的迴文。
狀態轉移:由迴文的定義可知dp[1][1][0][0],dp[0][0][1][1]為1,然後就是轉移,這個有四個轉移,但是大意都是一樣的,當x[i]==x[j]時,我們可以得知如果dp[i-1,j-1][k,n]如果為迴文,那麼dp[i,j][k,n]肯定也為迴文,剩下三個和這個意思一樣。剩下的就是區間dp的基本,要從子最優得到當前的最優。
#include<bits/stdc++.h>
using namespace std;
int dp[55][55][55][55];
int main()
{
char x[55], y[55];
int t;
cin >> t;
while(t--)
{
int ans = 0;
cin >> x + 1 >> y + 1;
int l = strlen(x + 1), l1 = strlen(y + 1);
for (int x1 = 0; x1 <= l;x1++)
{
for (int y1 = 0; y1 <= l1;y1++)
{
for (int i = 1, j = x1; j <= l;i++,j++)
{
for (int k = 1, n = y1; n <= l1;k++,n++)
{
if(x1+y1<=1)
dp[ i][j][k][n] = 1;//這個別忘了
else
{
dp[i][j][k][n] = 0;
if(x[i]==x[j]&&x1>1)
if(dp[i+1][j-1][k][n])
dp[i][j][k][n] = 1;
if(x[j]==y[k]&&x1&&y1)
if(dp[i][j-1][k+1][n])
dp[i][j][k][n] = 1;
if(x[i]==y[n]&&x1&&y1)
if(dp[i+1][j][k][n-1])
dp[i][j][k][n] = 1;
if(y[k]==y[n]&&y1>1)
if(dp[i][j][k+1][n-1])
dp[i][j][k][n] = 1;
}
if(dp[i][j][k][n])
ans = max(ans, x1 + y1);
}
}
}
}
cout << ans << endl;
}
return 0;
}