【AGC007F】Shik and Copying String【贪心】【队列】
程序员文章站
2022-03-11 23:30:05
...
画一个折线图。每一行表示一次复制,每一列表示一个位置,红线表示字母确定过程的路线。
则我们可以从T串从右往左贪心取,使得折线尽量靠右。可以证明这样子是最优的。
具体实现时,我们可以维护一个队列,里面存在若干的T中的位置和S中匹配尽量靠后匹配位置的最大值,而且要满足这些位置和当前位置是相互影响的,也就是两个位置的折线会交在一起。这样子我们就要开队列大小+1层,使得不会冲突。
#include<cstdio>
#include<cstring>
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
const int N=1000005;
int n,pos,ans,head,tail,q[N];
char s[N],t[N];
int main(){
scanf("%d%s%s",&n,s+1,t+1);
if(!strcmp(s+1,t+1)){
puts("0");
return 0;
}
pos=n;
head=1,tail=0;
for(int i=n;i>=1;i--){
if(t[i]==t[i-1]){
continue;
}
pos=min(pos,i);
while(pos&&t[i]!=s[pos]){
pos--;
}
if(!pos){
puts("-1");
return 0;
}
while(head<=tail){
if(q[head]-(tail-head+1)+1>i){
head++;
}else{
break;
}
}
q[++tail]=pos;
if(i!=pos){
ans=max(ans,tail-head+1);
}
}
printf("%d\n",ans+1);
return 0;
}
下一篇: 切香肠(二分答案+贪心)