牛客NC13230 合併回文子串

2021-10-06 05:02:02 字數 2340 閱讀 1384

題目鏈結

題目描述

輸入兩個字串a和b,合併成乙個串c,屬於a和b的字元在c中順序保持不變。如"abc"和"xyz"可以被組合成"axbycz"或"abxcyz"等。

我們定義字串的價值為其最長回文子串的長度(回文串表示從正反兩邊看完全一致的字串,如"aba"和"xyyx")。

需要求出所有可能的c中價值最大的字串,輸出這個最大價值即可

輸入描述:

第一行乙個整數t(t ≤ 50)。

接下來2t行,每兩行兩個字串分別代表a,b(|a|,|b| ≤ 50),a,b的字符集為全體小寫字母。

輸出描述:

對於每組資料輸出一行乙個整數表示價值最大的c的價值。

示例1輸入2aa

bbaaaaabcaa

輸出45

這是一道區間dp的問題,感覺很多回文串的問題都是運用dp然後考慮頭尾兩個元素的值的關係然後確定轉移方程。這題也不例外了,但是dp的含義和dp的方式有些特別。首先設dp[i][j][k][l]代表從a串中取第i個元素到第j個元素,然後在b中取第k個元素到第l個元素,看是否能組成回文串,可以為1,不能則為0,這裡有一點要注意,不是從這兩個範圍裡面分別選若干個元素去組合回文串,是要把範圍內每個都選上,若是選若干個,那麼只要在a或b中選乙個字母,然後另乙個不選,那麼這必能構成回文串,所以那樣的dp的含義就沒有什麼意義,無法深入到具體情況,而且對於同乙個串而言,選擇的字母必須要連續,因為題目表明「屬於a和b的字元在c中順序保持不變」,所以一定是連續的取範圍中的每乙個。然後就是轉移方程,轉移方程的思路就是考慮頭尾,因為取的範圍我們知道,那麼頭尾的組合只有四種情況(前頭後尾)(1):a[i] a[j](2):a[i] b[l](3):b[k] b[l](4):b[k] a[j]。然後我們就可以得到下列轉移方程(先忽略裡面的x和y,這是和轉移方式有關的引數):

if

(a[i-1]

==a[j-1]

&&x>1)

dp[i]

[j][k]

[l]|

=dp[i+1]

[j-1

][k]

[l];

if(b[k-1]

==b[l-1]

&&y>1)

dp[i]

[j][k]

[l]|

=dp[i]

[j][k+1]

[l-1];

if(a[i-1]

==b[l-1]

&&x&&y)

dp[i]

[j][k]

[l]|

=dp[i+1]

[j][k]

[l-1];

if(a[j-1]

==b[k-1]

&&x&&y)

dp[i]

[j][k]

[l]|

=dp[i]

[j-1

][k+1]

[l];

那麼注意,裡面用的不是等於,是或與,為什麼呢?因為每種情況只是對應於一種擺放頭尾的情況,所以一種不行不代表其他的不行,但是如果我已經判斷到一種情況可以就想不要被其他情況影響,所以用或與可以完美適配這個問題,當然,其他的寫法肯定是可以的,只是或與看起來比較簡潔。如果乙個條件都不滿足的話就肯定是不行了,因為所有可能的頭尾的情況都無法滿足,那麼就一定無法構成回文串了,當dp裡面元素初始化為0的話就自然就不用處理了這種情況了。

那麼我們要求的是長度,乍一眼一看好像很簡單,我們是可以知道我們兩個子串具體取到哪個範圍的,所以具體有多少個字元是可以通過i,j,k,l中算出來的,但是這裡我們要和轉移方程結合來看,我們轉移的時候一定要保證等號右邊是要已經求出來了的。所以我們通過觀察可以發現,對於求dp[i][j][k][l]來說,等號右邊都是a或者b長度縮減了的情況,所以我們只要對長度去dp就好了,那麼也就是上面的**中的x和y了,裡面所有關於x和y的判斷條件其實都是乙個含義:若是兩個串一共只取乙個元素就直接是回文串,其他情況至少兩個元素才能構成頭尾。

#include

#include

#include

using

namespace std;

int dp[52]

[52][

52][52

];intmain()

if(dp[i]

[j][k]

[l])

ans=

max(ans,x+y);}

printf

("%d\n"

,ans);}

}

NC13230 合併回文子串(區間dp)

從資料範圍不難推出可以用f,表示由兩個字串來表示的最長大小 並且因為是回文串,所以我們要向頭尾加字元,來變大,因為這個是回文子串,也就是連續的一段。include include include include include using namespace std const int n 55 c...

合併回文子串

學習周記 時間限制 c c 2秒,其他語言4秒 空間限制 c c 262144k,其他語言524288k 64bit io format lld 題目描述 輸入兩個字串a和b,合併成乙個串c,屬於a和b的字元在c中順序保持不變。如 abc 和 xyz 可以被組合成 axbycz 或 abxcyz 等...

合併回文子串

輸入兩個字串a和b,合併成乙個串c,屬於a和b的字元在c中順序保持不變。如 abc 和 xyz 可以被組合成 axbycz 或 abxcyz 等。我們定義字串的價值為其最長回文子串的長度 回文串表示從正反兩邊看完全一致的字串,如 aba 和 xyyx 需要求出所有可能的c中價值最大的字串,輸出這個最...