字符串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; }