Problem:

输入两个字符串A和B,合并成一个串C,属于A和B的字符在C中顺序保持不变。如"abc"和"xyz"可以被组合成"axbycz"或"abxcyz"等。
我们定义字符串的价值为其最长回文子串的长度(回文串表示从正反两边看完全一致的字符串,如"aba"和"xyyx")。
需要求出所有可能的C中价值最大的字符串,输出这个最大价值即可

Solution:

题中需要求的是a和b合并之后的最大回文子串是多长。
我们假设当前有一个字符串c,他是由a中的la到ra之间的字符串和b中的lb和rb之间的字符串组成,那么对于c来说,组成回文串有以下可能
(1)a(la+1,ra-1) + b(lb,rb) 是回文串,并且a[la] == a[ra]
(2)a(la,ra) + b(lb + 1,rb - 1) 是回文串,并且b[lb] == b[rb]
(3)a(la + 1,ra) + b(lb,rb - 1) 是回文串,并且a[la] == b[rb]
(4)a(la,ra - 1) + b(lb + 1,rb) 是回文串,并且a[ra] == b[lb]
因此,我们就找出了状态方程dp[la][ra][lb][rb],表示的是a(la,ra) + b(lb,rb)能否组成回文串
我们需要找到方程的储实状态,这里的初始状态即为1个字符的时候,因为它一定是回文串,因此我们需要从初始状态开始往后求解答案,
所以我们可以首先遍历a和b的长度(从0-len),然后在遍历他们的起点la,lb
当ra - la + 1 + rb - lb + 1 <= 1时, dp[la][ra][lb][rb]=1
否则 dp[la][ra][lb][rb] |= (1)|(2)|(3)|(4)

// https://ac.nowcoder.com/acm/problem/13230
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define _for(i,s,t) for(int i=s;i<t;i++)
#define _rof(i,s,t) for(int i=s;i>t;i--)
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define Ri(x) scanf("%d",&x)
#define Rii(x,y) scanf("%d%d",&x,&y)
#define INF 0x3f3f3f3f
using namespace std;
template<class T>inline void read(T &res)
{
    char c;T flag=1;
    while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}
typedef long long ll;
const int maxn = 50 + 10;
bool dp[maxn][maxn][maxn][maxn];
string A,B;
int ans;
int main(){
    IOS;
    int T;
    cin>>T;
    while(T--){
        cin>>A>>B;
        ans = 1;
        int lena = A.length(),lenb = B.length();
        rep(len_a,0,lena) rep(len_b,0,lenb){
            for(int la = 1;len_a + la - 1 <= lena;la ++) for(int lb = 1;len_b + lb - 1 <= lenb;lb ++){
                int ra = len_a + la - 1;
                int rb = len_b + lb - 1;
                if(len_a + len_b <= 1){
                    dp[la][ra][lb][rb] = 1;
                }else{
                    dp[la][ra][lb][rb] = 0;
                    dp[la][ra][lb][rb] |= (dp[la + 1][ra - 1][lb][rb] && A[la - 1] == A[ra - 1]);
                    dp[la][ra][lb][rb] |= (dp[la + 1][ra][lb][rb - 1] && A[la - 1] == B[rb - 1]);
                    dp[la][ra][lb][rb] |= (dp[la][ra - 1][lb + 1][rb] && A[ra - 1] == B[lb - 1]);
                    dp[la][ra][lb][rb] |= (dp[la][ra][lb + 1][rb - 1] && B[lb - 1] == B[rb - 1]);
                }
                if(dp[la][ra][lb][rb]){
                    ans = max(ans,ra - la + 1 + rb - lb + 1);
                }
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}
/**
Problem:
输入两个字符串A和B,合并成一个串C,属于A和B的字符在C中顺序保持不变。如"abc"和"xyz"可以被组合成"axbycz"或"abxcyz"等。
我们定义字符串的价值为其最长回文子串的长度(回文串表示从正反两边看完全一致的字符串,如"aba"和"xyyx")。
需要求出所有可能的C中价值最大的字符串,输出这个最大价值即可

Solution: 
题中需要求的是a和b合并之后的最大回文子串是多长。
我们假设当前有一个字符串c,他是由a中的la到ra之间的字符串和b中的lb和rb之间的字符串组成,那么对于c来说,组成回文串有以下可能 
(1)a(la+1,ra-1) + b(lb,rb) 是回文串,并且a[la] == a[ra]
(2)a(la,ra) + b(lb + 1,rb - 1) 是回文串,并且b[lb] == b[rb] 
(3)a(la + 1,ra) + b(lb,rb - 1) 是回文串,并且a[la] == b[rb]
(4)a(la,ra - 1) + b(lb + 1,rb) 是回文串,并且a[ra] == b[lb]
因此,我们就找出了状态方程dp[la][ra][lb][rb],表示的是a(la,ra) + b(lb,rb)能否组成回文串
我们需要找到方程的储实状态,这里的初始状态即为1个字符的时候,因为它一定是回文串,因此我们需要从初始状态开始往后求解答案,
所以我们可以首先遍历a和b的长度(从0-len),然后在遍历他们的起点la,lb
当ra - la + 1 + rb - lb + 1 <= 1时, dp[la][ra][lb][rb]=1
否则 dp[la][ra][lb][rb] |= (1)|(2)|(3)|(4) 
*/