合并回文子串
活动地址:https://ac.nowcoder.com/discuss/391086?type=101
思路
这是一道比较典型的区间dp题目,而区间dp很多时候都是小区间算好了结果,看能不能在此基础上更新大区间,这题也是如此。
这里我做了图解:
所以我们只需要把初始化工作做好,然后推下去就好。也就是把字符串长度为0和1的f[i,j][l,r] 设置成true就行了
代码
#include <iostream> #include <algorithm> #include <string> #include <cstring> #include <map> #include <set> #include <deque> #include <queue> #include <vector> #include <cstring> #include <cstdio> #include <cstdlib> #include <cmath> #define PI acos(-1) using namespace std; typedef long long ll; typedef pair<int,int> pii; const ll maxn = 1e6+10; double eps = 1e-8; int T; bool f[55][55][55][55]; char s1[55],s2[55]; int main(){ cin>>T; while(T--){ memset(f, false,sizeof f); int mx = 0; scanf("%s %s",s1+1,s2+1); int len1 = strlen(s1+1),len2 = strlen(s2+1); for(int L1 = 0;L1<=len1;L1++){ for(int L2 = 0;L2<=len2;L2++){ for(int i = 1;i<=len1-L1+1;i++){ for(int l = 1;l<=len2-L2+1;l++){ int j = i+L1-1,r = l+L2-1; bool &t = f[i][j][l][r]; //用引用方便些 if(L1+L2 <= 1) t = true; //初始化工作 else{//这里改变了一下,跟图片中倒着想一想就知道了 if(s1[i] == s1[j]) t |= f[i+1][j-1][l][r]; if(s2[l] == s2[r]) t |= f[i][j][l+1][r-1]; if(s1[i] == s2[r]) t |= f[i+1][j][l][r-1]; if(s1[j] == s2[l]) t |= f[i][j-1][l+1][r]; } if(t) mx = max(mx,L1+L2); } } } } printf("%d\n",mx); } return 0; }