[CF1303E] Erase Subsequences - dp

Solution

不由分说地枚举分割点

\(f[i][j]\) 表示原串处理到 \(i\)\(s_1\) 处理到 \(j\)\(s_2\) 最多能处理到哪里
采用主动转移
任意情况, \(f[i][j] \to f[i+1][j]\)
如果 \(s[i+1]=s_1[j+1]\) ,那么 \(f[i][j] \to f[i+1][j+1]\)
如果 \(s[i+1]=s_2[f[i][j]+1]\) ,那么 \(f[i][j]+1 \to f[i+1][j]\)
时间复杂度 \(O(n^3)\)

#include <bits/stdc++.h>
using namespace std;

int n,m,l1,l2;
char s[405],t[405],*s1,*s2;
int f[405][405];

void sh(int x,int &y) {
    y=max(x,y);
}

signed main() {
    ios::sync_with_stdio(false);
    int T;
    cin>>T;
    while(T--) {
        cin>>s+1>>t+1;
        n=strlen(s+1);
        m=strlen(t+1);
        int ans=0;
        for(int d=0;d<=m;d++) {
            s1=t;
            s2=t+d;
            l1=d;
            l2=m-d;
            memset(f,-0x3f,sizeof f);
            f[0][0]=0;
            {
                int i=0,j=0;
                sh(f[i][j],f[i+1][j]);
                if(s[i+1]==s1[j+1]) sh(f[i][j],f[i+1][j+1]);
                if(s[i+1]==s2[f[i][j]+1]) sh(f[i][j]+1,f[i+1][j]);
            }
            for(int i=1;i<=n;i++) {
                for(int j=0;j<=min(l1,i);j++) {
                    sh(f[i][j],f[i+1][j]);
                    if(s[i+1]==s1[j+1]) sh(f[i][j],f[i+1][j+1]);
                    if(f[i][j]>=0 && s[i+1]==s2[f[i][j]+1]) sh(f[i][j]+1,f[i+1][j]);
                }
            }
            if(f[n][l1]==l2) ans=1;
        }
        cout<<(ans>0?"YES":"NO")<<endl;
    }
}

猜你喜欢

转载自www.cnblogs.com/mollnn/p/12345851.html