合併迴文子串 區間dp

鏈接:https://ac.nowcoder.com/acm/problem/13230
來源:牛客網

題目描述
輸入兩個字符串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
輸入
2
aa
bb
a
aaaabcaa
輸出
4
5
很明顯這道題是dp題,因爲我們假設dp[i][j][k][p]表示的是選擇字符串a第i到j,字符串b第k到p的串。我們來思考下狀態轉移方程!
當a[i]==a[j]的時候,這個時候,最長的迴文串是什麼?毫無疑問,將a[i]與a[j]拼接到串a[i+1][j-1][k][p]當中即可。
當a[i]==b[p],b[k]==a[j],b[k]==b[p]都是如此。

注意寫區間dp要從小區間更新大區間,那怎麼做呢?枚舉區間長度即可!(邊界處理有點難)

#include<iostream>
#include<cstdio>
#define mmax 55
using namespace std;
int dp[55][55][55][55];
int main (){
    int T;
    cin>>T;
    while(T--){
    string a,b;
    cin>>a>>b;
    int len1=a.size();
    int len2=b.size();
    int inf=0;
    for(int i=0;i<=len1;i++){//第一段區間的長度
        for(int j=0;j<=len2;j++){//第二段區間的長度
            for(int k=0;k<=len1;k++){//第一段區間的起點,這裏要多出來一個空間
                int xend=k+i;//第一段區間終點+1
                if(xend>len1){//終點超出數組長度
                    break;
                }
                for(int p=0;p<=len2;p++){//第二段區間的起點
                    int yend=p+j;
                    if(yend>len2){
                        break;
                    }
                    int x=k,y=p;
                    if(i+j<=1){//不管選不選,小於等於一個字母一定是迴文串
                        dp[x][xend][y][yend]=1;
                    }
                    else{
                        dp[x][xend][y][yend]=0;
                        if(x<=xend-2&&a[x]==a[xend-1]){
                        dp[x][xend][y][yend]|=dp[x+1][xend-1][y][yend];
                    }
                        if(x+1<=xend&&y<=yend-1&&a[x]==b[yend-1]){
                        dp[x][xend][y][yend]|=dp[x+1][xend][y][yend-1];
                    }
                        if(x<=xend-1&&y+1<=yend&&b[y]==a[xend-1]){
                        dp[x][xend][y][yend]|=dp[x][xend-1][y+1][yend];
                    }
                        if(y<=yend-2&&b[y]==b[yend-1]){
                        dp[x][xend][y][yend]|=dp[x][xend][y+1][yend-1];
                    }
                    }
                    if(dp[x][xend][y][yend])
                    inf=max(inf,i+j);
                   // printf("%d %d %d %d %d\n",x,xend,y,yend,dp[x][xend][y][yend]);
                }
            }
        }
    }
        cout<<inf<<endl;
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章