吐槽
我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;
}