2020ICPC·小米 网络选拔赛第二场 I Subsequence Pair

题意:求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('\n')
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\n",ans);
    }
	return 0;
}






posted @ 2020-11-03 20:39  GhostCai  阅读(52)  评论(0编辑  收藏  举报