Codeforces 1303E Erase Subsequences (子序列匹配)

题意

给你长度为500的串a,b,问你是否存在一种b的划分方式,使得b的两个子串是a的两个不重合的子序列

思路

先枚举分割点
\(f[i][j]\)为a串处理到i,b串处理到j时,b串的两个子串个匹配成功了多少
那么我们先枚举n,再枚举m,再维护一下\(b_1\)串匹配了i个时\(b_2\)串匹配成功的最大值,\(b_2\)串匹配了i个时\(b_1\)串匹配成功的最大值
然后从上一行转移即可
写出来发现是个dp..

代码

比赛时没清空0,错失好几十分

int n,m;
char a[maxn],b[maxn];
vector<PI>v;
int hang[555],lie[555];
int main() {
    #define mp make_pair 
    int t;
    scanf("%d", &t);
    while(t--){
        v.clear();
        scanf("%s",a+1);
        n=strlen(a+1);
        scanf("%s",b+1);
        m=strlen(b+1);
        int R = -1;
        int ok = 0;
        for(R = 0; R <= n; R++){
            v.clear();
            for(int i = 0; i <= n; i++){
                lie[i]=hang[i]=-1;
            }
            
            for(int i = 1; i <= n; i++){
                v.clear();
                for(int j = 1; j <= m; j++){
                    if(a[i]==b[j]){
                        if(j<=R){
                            int x = -1;
                            if(hang[j-1]!=-1)x=hang[j-1];
                            if(j==1&&x==-1)x=0;
                            if(x!=-1)v.pb(mp(j,x));
                        }
                        else{
                            int x = -1;
                            if(lie[j-R-1]!=-1)x=lie[j-R-1];
                            if(j==R+1&&x==-1)x=0;
                            if(x!=-1)v.pb(mp(x,j-R));
                        }
                    }
                }
                for(int j = 0; j <(int)v.size(); j++){
                    int x = v[j].fst;
                    int y = v[j].sc;
                    hang[x]=max(hang[x],y);
                    lie[y]=max(lie[y],x);;
                    if(x==R&&y==m-R)ok=1;
                }
                v.clear();
            }
        }
        if(ok){
            printf("YES\n");
        }
        else printf("NO\n");
    }
 
    return 0;
}
posted @ 2020-02-16 17:03  wrjlinkkkkkk  阅读(199)  评论(0编辑  收藏  举报