Educational Codeforces Round 82 (Rated for Div. 2)E. Erase Subsequences
题目链接
 题意:给你两个字符串     s,t,问你     t是否可以由     s的两个不相交子序列构成。
 思路:显然我们应该枚举     t的断点     i,使得     [1,i]为一个子序列     [i+1,lent]为第二个子序列。然后check这种情况是否合法.我们设前一半为     L,后一半为     R
      dp[i][j]表示当前匹配到     Li,Rj在     s中的最小位置。
 若     dp[lenL][lenR]<=lens即合法。
 转移用序列自动机优化一下即可.
 注意一下细节问题.
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
int t;
char a[N],b[N];
int dp[403][403];
int nx[555][26];
int main() {
  ios::sync_with_stdio(false);
  for(cin>>t;t;t--){
    cin>>a+1>>b+1;
    int l=strlen(a+1);
    int r=strlen(b+1);
    for(int i=0;i<26;i++)nx[l+1][i]=nx[l+2][i]=l+1;
    for(int i=l;i>=1;i--){
      for(int j=0;j<26;j++)nx[i][j]=nx[i+1][j];
      nx[i][a[i]-'a']=i;
    }
    int ok=0;
    for(int i=0;i<r;i++){
      memset(dp,-1,sizeof dp);
      dp[0][i]=0;
      for(int j=0;j<=i;j++){
        for(int k=i;k<=r;k++){
          if(j==0&&k==i)
            continue;
          dp[j][k]=l+1;
          if(j) dp[j][k]=min(dp[j][k],nx[dp[j-1][k]+1][b[j]-'a']);
          if(k>i)dp[j][k]=min(dp[j][k],nx[dp[j][k-1]+1][b[k]-'a']);
        }
      }
      if(dp[i][r]<=l){
        ok=1;
        //cout<<i<<' '<<r<<' '<<dp[i][r]<<endl;
        break;
      }
    }
    if(ok)cout<<"YES\n";
    else cout<<"NO\n";
  }
  return 0;
}
 查看7道真题和解析
查看7道真题和解析