A.先放一个2再放一个1,然后全放2,然后全放1即可。
B.f[i][j][k]表示三个串分别匹配到第i,j,k位的最短合法前缀。当某串新增一个字符时,枚举另外两维更新,转移讨论合法前缀的最后一位是哪个字符串的即可。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 6 typedef long long ll; 7 using namespace std; 8 9 const int N=200010,M=300; 10 char op,ch,S[N],S1[M],S2[M],S3[M]; 11 int n,Q,x,s1,s2,s3,nxt[N][30],f[M][M][M]; 12 13 int main(){ 14 scanf("%d%d%s",&n,&Q,S+1); 15 rep(i,0,25) nxt[n+1][i]=nxt[n+2][i]=n+1; 16 for (int i=n; i; i--){ 17 rep(j,0,25) nxt[i][j]=nxt[i+1][j]; 18 nxt[i][S[i]-'a']=i; 19 } 20 rep(i,0,250) rep(j,0,250) rep(k,0,250) f[i][j][k]=n+1; 21 f[0][0][0]=0; 22 while (Q--){ 23 scanf(" %c%d",&op,&x); 24 if (op=='-'){ 25 if (x==1) s1--; 26 if (x==2) s2--; 27 if (x==3) s3--; 28 }else{ 29 scanf(" %c",&ch); 30 if (x==1){ 31 S1[++s1]=ch; 32 rep(i,0,s2) rep(j,0,s3){ 33 int res=nxt[f[s1-1][i][j]+1][ch-'a']; 34 if (i) res=min(res,nxt[f[s1][i-1][j]+1][S2[i]-'a']); 35 if (j) res=min(res,nxt[f[s1][i][j-1]+1][S3[j]-'a']); 36 f[s1][i][j]=min(n+1,res); 37 } 38 } 39 if (x==2){ 40 S2[++s2]=ch; 41 rep(i,0,s1) rep(j,0,s3){ 42 int res=nxt[f[i][s2-1][j]+1][ch-'a']; 43 if (i) res=min(res,nxt[f[i-1][s2][j]+1][S1[i]-'a']); 44 if (j) res=min(res,nxt[f[i][s2][j-1]+1][S3[j]-'a']); 45 f[i][s2][j]=min(n+1,res); 46 } 47 } 48 if (x==3){ 49 S3[++s3]=ch; 50 rep(i,0,s1) rep(j,0,s2){ 51 int res=nxt[f[i][j][s3-1]+1][ch-'a']; 52 if (i) res=min(res,nxt[f[i-1][j][s3]+1][S1[i]-'a']); 53 if (j) res=min(res,nxt[f[i][j-1][s3]+1][S2[j]-'a']); 54 f[i][j][s3]=min(n+1,res); 55 } 56 } 57 } 58 if (f[s1][s2][s3]<=n) puts("YES"); else puts("NO"); 59 } 60 return 0; 61 }