题意:给定字符串s和t,字符串z每次都可以从s取一个子序列,问z最少拿几次可以变成t?
思路:一开始想dp,一看数据量感觉不对呀,然后就想到了这个做法,nx【i】【j】表示当前i位置的第j个字符的位置,但比赛时这题的bug几乎调到崩溃(QAQ),总是有个别答案少1,又不知道怎么优化,还是老老实实将nx后移吧,也就是比如样例的aabce,后移后就是0aabce,只要遍历t数组依次跳就可以了。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+1;
char s[maxn],t[maxn];
int nx[maxn][27];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int flag=0;
scanf("%s %s",s,t);
int len=strlen(s),ans=0,now=0;
for(int i=0;i<26;++i) nx[len][i]=0;
for(int i=len-1;i>=0;--i)
{
for(int j=0;j<26;++j)
nx[i][j]=nx[i+1][j];
nx[i][s[i]-'a']=i+1;
}
len=strlen(t);
for(int i=0;i<len;++i)
{
int k=t[i]-'a';
if(nx[now][k]!=0) now=nx[now][k];
else{
ans++;
now=0;
if(!nx[0][k]) {
flag=1;break;}
now=nx[now][k];
}
}
printf("%d\n",flag?-1:ans+1);
}
}