贪心+队列
画出折线图,每一列表示一个位置,每一行表示一次copy,折线段表示覆盖。一个过程就相当于从第一行开始不断向下画折线来覆盖最后一行。根据贪心,显然折线应贴着上面来画,且转移一定是从最近的转移过来。瞎JB感受一下就会发现折线每次至多增加一格,因此只要维护这些折线的拐点,也就是差分点就可以了,用一个队列维护即可。以上口胡,目测讲不清楚。详情还是去看题解吧。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 1000005
using namespace std;
namespace runzhe2000
{
int n, q[N], head = N-1, tail = N-1, ans;
char s[N], t[N];
void main()
{
scanf("%d%s%s",&n,s+1,t+1); int tag = 0;
if(!strcmp(s+1,t+1)){puts("0");return;}
for(int l = n+1, r = n, pl = n+1, pr = n+1; r; r = l - 1)
{
for(; t[l-1] == t[r]; l--);
for(pr = pl-1; s[pl-1] == s[pr]; pl--);
for(; (pl > l || s[pr] != t[r]) && pr; )
for(pr = pl-1; s[pl-1] == s[pr] && pr; pl--);
if(!pr){puts("-1");return;}
pl = max(pl, min(l,pr));
for(; tail-head && q[tail-1]+tag > r; --tail);
tag--; q[--head] = pl-tag;
ans = max(ans, tail-head);
}
printf("%d\n",ans);
}
}
int main()
{
runzhe2000::main();
}