吐槽:
我TM人都傻了,为什么这两种写法在牛客机子评测时会补题呢?是数据的锅吗?
(1)
(2)
这两种写法有什么区别呢?难道是我对break函数有误解?
思路
回文子串的构造,一般都是某一个回文子串两边同时加上一个相同的字符。
所以我们就可以想到用dp[i][j][x][y]表示串a中i-j与串b中x-y能不能构成回文子串?
如果串a中i-j与串b中x-y能构成回文子串? 它可能由哪些状态更新过来的呢?
串a中(i + 1) - (j - 1)与串b中x-y转移
串a中(i + 1) - (j)与串b中x-(y-1)转移
串a中i - (j - 1)与串b中(x + 1)-y转移
串a中i - j与串b中(x + 1)-(y - 1)转移
#include <bits/stdc++.h> using namespace std; typedef long long ll; char a[100], b[100]; int dp[100][100][100][100]; int len1, len2, n, m, ans; int main(){ int t; scanf("%d", &t); while(t--){ ans = 0; scanf("%s%s", a + 1, b + 1); n = strlen(a + 1); m = strlen(b + 1); for(int len1 = 0; len1 <= n; len1++){ for(int len2 = 0; len2 <= m; len2++){ for(int i = 1, j; i + len1 - 1 <= n; i++){ j = len1 + i - 1; if(j > n) break; for(int x = 1, y; x + len2 - 1 <= m; x++){ y = len2 + x - 1; if(y > m) break; if(len1 + len2 <= 1) dp[i][j][x][y] = 1; else{ dp[i][j][x][y] = 0; if(len1 >= 2) dp[i][j][x][y] |= (dp[i + 1][j - 1][x][y] && (a[i] == a[j])); if(len1 && len2) dp[i][j][x][y] |= (dp[i + 1][j][x][y - 1] && (a[i] == b[y])); if(len2 >= 2) dp[i][j][x][y] |= (dp[i][j][x + 1][y - 1] && (b[x] == b[y])); if(len1 && len2) dp[i][j][x][y] |= (dp[i][j - 1][x + 1][y] && (b[x] == a[j])); } //printf("a:(%d, %d) b:(%d, %d) = %d\n", i, j, x, y, dp[i][j][x][y]); if(dp[i][j][x][y]) ans = max(ans, len1 + len2); } } } } printf("%d\n", ans); } return 0; }