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;
}