AtCoder agc007_f Shik and Copying String

贪心+队列

画出折线图,每一列表示一个位置,每一行表示一次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();
}   
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值