字符串c中价值最大的子串一定是由A中的某个子串和B中的某个子串组成的。
那么对于已知的dp[i][j][k][l]的状态,可以转移到取A字符串两边放到C字符串两边。
可以是取B字符串两边放到C字符串两边。
可以是取A字符串的右边和B字符串的左边来放到C字符串的两边
可以是取A字符串左边和B字符串的右边来放到C字符串的两边。
那么状态转移方程为:
// if (a[i]==a[j]) dp[i][j][k][l] |= dp[i+1][j-1][k][l];
// if (b[k]==b[l]) dp[i][j][k][l] |= dp[i][j][k+1][l-1];
// if (a[i]==b[l]) dp[i][j][k][l] |= dp[i+1][j][k][l-1];
// if (a[j]==b[k]) dp[i][j][k][l] |= dp[i][j-1][k+1][l];
那么对于已知的dp[i][j][k][l]的状态,可以转移到取A字符串两边放到C字符串两边。
可以是取B字符串两边放到C字符串两边。
可以是取A字符串的右边和B字符串的左边来放到C字符串的两边
可以是取A字符串左边和B字符串的右边来放到C字符串的两边。
那么状态转移方程为:
// if (a[i]==a[j]) dp[i][j][k][l] |= dp[i+1][j-1][k][l];
// if (b[k]==b[l]) dp[i][j][k][l] |= dp[i][j][k+1][l-1];
// if (a[i]==b[l]) dp[i][j][k][l] |= dp[i+1][j][k][l-1];
// if (a[j]==b[k]) dp[i][j][k][l] |= dp[i][j-1][k+1][l];
//字符串c中价值最大的子串一定是由A中的某个子串和B中的某个子串组成的。
//那么对于已知的dp[i][j][k][l]的状态,可以转移到取A字符串两边放到C字符串两边。
//可以是取B字符串两边放到C字符串两边。
//可以是取A字符串的右边和B字符串的左边来放到C字符串的两边
//可以是取A字符串左边和B字符串的右边来放到C字符串的两边。
//那么状态转移方程为:
// if (a[i]==a[j]) dp[i][j][k][l] |= dp[i+1][j-1][k][l];
// if (b[k]==b[l]) dp[i][j][k][l] |= dp[i][j][k+1][l-1];
// if (a[i]==b[l]) dp[i][j][k][l] |= dp[i+1][j][k][l-1];
// if (a[j]==b[k]) dp[i][j][k][l] |= dp[i][j-1][k+1][l];
#include <bits/stdc++.h>
using namespace std;
const int maxn = 55;
int dp[maxn][maxn][maxn][maxn];
string a, b;
int main() {
int T;
cin>>T;
while (T--) {
cin>>a>>b;
a = " "+a;b = " "+b;
memset(dp, 0, sizeof(dp));
int ans = 1;
for (int x=0;x<=a.size()-1;x++) {
for (int y=0;y<=b.size()-1;y++) {
for (int i=1;i+x-1<=a.size()-1;i++) {
for (int k=1;k+y-1<=b.size()-1;k++) {
int j = i+x-1, l = k+y-1;
if (x+y<=1) {
dp[i][j][k][l] = 1;
}
else {
// if (x>=3)
if (a[i]==a[j]) dp[i][j][k][l] |= dp[i+1][j-1][k][l];
if (b[k]==b[l]) dp[i][j][k][l] |= dp[i][j][k+1][l-1];
// if (x&&y) {
if (a[i]==b[l]) dp[i][j][k][l] |= dp[i+1][j][k][l-1];
if (a[j]==b[k]) dp[i][j][k][l] |= dp[i][j-1][k+1][l];
// }
}
//
if (dp[i][j][k][l]) {
ans = max(ans, x+y);
}
}
}
}
}
cout<<ans<<endl;
}
return 0;
}

京公网安备 11010502036488号