题意:求S和T的子序列s,t,使s<=t,最大化len(s)+len(t)
设f[i][j]表示S的前缀i和T的前缀j的最长合法子序列长度
有点类似LCS,但f[i][j]表示的“合法”不是字典序小于等于,仍是LCS的严格等于,这样便于区分
s为t前缀的情况,统计答案的时候算入后面的部分即可
复杂度(O(n^2))
/*
* Author : GhostCai
* Expecto Patronum
*/
#include<bits/stdc++.h>
using namespace std;
void debug_out() { cerr << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
cerr << " " << H;
debug_out(T...);
}
#define debug(...)
cerr << __LINE__ << " [" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#define rep(x,y,z) for(int x=y;x<=z;x++)
inline int rd(){
int ret=0,f=1;char c;
while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
while(isdigit(c))ret=ret*10+c-'0',c=getchar();
return ret*f;
}
#define pc putchar
#define space() pc(' ')
#define nextline() pc('
')
void pot(int x){if(!x)return;pot(x/10);pc('0'+x%10);}
void out(int x){if(!x)pc('0');if(x<0)pc('-'),x=-x;pot(x);}
const int MAXN = 2005;
char a[MAXN],b[MAXN];
int f[MAXN][MAXN];
int ans;
int main(){
while(~scanf("%s%s",a+1,b+1)){
memset(f,0,sizeof(f));
int lena=strlen(a+1),lenb=strlen(b+1);
ans=lenb;
rep(i,1,lena){
rep(j,1,lenb){
f[i][j]=max(f[i-1][j],f[i][j-1]);
if(a[i]<b[j]){
// f[i][j]=f[i-1][j-1]+2;
ans=max(ans,f[i-1][j-1]+lena-i+lenb-j+2);
}else if(a[i]==b[j]){
f[i][j]=max(f[i][j],f[i-1][j-1]+2);
}
ans=max(ans,f[i][j]+lenb-j);
}
}
printf("%d
",ans);
}
return 0;
}