AtCoder agc007_f Shik and Copying String

贪心+队列

画出折线图,每一列表示一个位置,每一行表示一次copy,折线段表示覆盖。一个过程就相当于从第一行开始不断向下画折线来覆盖最后一行。根据贪心,显然折线应贴着上面来画,且转移一定是从最近的转移过来。瞎JB感受一下就会发现折线每次至多增加一格,因此只要维护这些折线的拐点,也就是差分点就可以了,用一个队列维护即可。以上口胡,目测讲不清楚。详情还是去看题解吧。

#include
#include
#include
#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();
}   

你可能感兴趣的:(其它-贪心,数据结构-队)