luogu P1484 种树

5 篇文章 0 订阅
4 篇文章 0 订阅

这个题的解法我是在河南听过的; 但是尴尬; 没好好听,所以忘了; 大致意思就是:

选k个数,要求选的任意两个数不能相邻;
大致是一种抵消的反悔方式;

假设我们当前选了a[i],那么如果我们下次选了a[i-1] and a[i+1], 那么他们的代价差是:a[i-1]+a[i+1]-a[i]; 所以我们把 a[i] = a[i-1]+a[i+1]-a[i]; then a[i-1] and a[i+1] delele , 这样如果我们反悔,想要选a[i]’s(both sides); 就等价于再选一次a[i]; 所以放回a[i]; 用堆维护; 然后要注意 delele 的方式;


主要部分

  for(R II i=1;i<=n;i++) 
    {
        Q.push((node) {i,a[i]});
        l[i]=i-1; r[i]=i+1;
    }

    while (k--) {
        while (!Q.empty() && had[Q.top().wei]) Q.pop();
        if(Q.empty() || Q.top().x<0) break ;
        R II wei=Q.top().wei;
        R II x=Q.top().x;
        Q.pop();
        ans+=x;
        a[wei]=a[l[wei]]+a[r[wei]]-a[wei];
        had[l[wei]]=had[r[wei]]=1;
        l[wei]=l[l[wei]]; r[wei]=r[r[wei]];
        l[r[wei]]=wei; r[l[wei]]=wei;
        // 记录两侧来实现删;
        Q.push((node) {wei,a[wei]});
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值