貪心+隊列
畫出折線圖,每一列表示一個位置,每一行表示一次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();
}