codeforces-Ed81-C

codeforces-Ed81-C

七月 08, 2020

C - Obtain The String

题意
给出s串 和目标串t
你可以从s串中取出任意子序列拼接
问最少取出几个子序列才能拼出目标串t

题解

发现 如果t串某个字母需要取到 t上一个字母在s串中取得字符的位置之前
那么结果就需要增加一个子序列产能拼接出t

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# include<bits/stdc++.h>

using namespace std;
typedef long long ll;

# define IO std::ios::sync_with_stdio(false);

# define endl '\n'

string s,t;
const int maxn=(int)1e6+5;
int first[30];
int have[30][(int)1e5+5];
int main() {
int T;cin>>T;
while(T--){
cin>>s>>t;
int lens=s.size();
for(int i=0;i<30;i++)first[i]=-1;
for(int i=0;i<lens;i++){
if(first[s[i]-'a']==-1)first[s[i]-'a']=i;
for(int j=0;j<30;j++)have[j][i]=maxn;
}
for(int i=0;i<30;i++)have[i][lens]=maxn;
for(int i=lens-1;i>=0;i--){
have[s[i]-'a'][i]=i;
for(int j=0;j<30;j++){
have[j][i]=min(have[j][i],have[j][i+1]);
}
}
int lent=t.size();int per=-1,ans=1;bool flag=1;
for(int i=0;i<lent;i++){
//cout<<first[t[i]-'a']<<" "<<per<<endl;
if(first[t[i]-'a']==-1){flag=0;break;}
bool vis=0;
if(first[t[i]-'a']<=per&&have[t[i]-'a'][per+1]==maxn)ans++,vis=1;
if(vis)per=first[t[i]-'a'];
else per=have[t[i]-'a'][per+1];

}
if(flag)cout<<ans<<endl;
else cout<<-1<<endl;
}

}