【Luogu1484】种树(贪心,堆)

举报
小哈里 发表于 2022/05/10 23:12:17 2022/05/10
【摘要】 problem 在一条直线上有n个坑,要种k棵树。不能在相邻两个坑种树。已知在每个坑种树会有一个获利,求最大获利。n<=5e5,k<=n/2 solution 考虑限制条件:对于每个位置...

problem

  • 在一条直线上有n个坑,要种k棵树。
  • 不能在相邻两个坑种树。
  • 已知在每个坑种树会有一个获利,求最大获利。
  • n<=5e5,k<=n/2

solution

  • 考虑限制条件:对于每个位置id,我们都可以选择ans = max(v[id], v[ l[ id ] ]+v[ r[ id ]])
  • 贪心:首先将全部的坑丢入大根堆中,然后从枚举1到k,每次取出获利最大的坑种树。最多种满k个坑(可以中不满,为负的话去种它就没有意义)
  • 限制:对于限制条件,我们采用缩点(对于每个点,不管选择了v[id]还是v[l[id]]+v[r[id]], 这三个位置肯定都不能用了,且选择v[l[id]]+v[r[id]]时他们左右的两个坑也没用了。于是我们新建一个点num代替这三个点,把l[l[id]],r[r[id]]连到num,再维护其左右端点值。) + 后悔(我们在堆中维护v[l[id]]+v[r[id]]-v[id],那么如果下次取出来一个正数,相当于没选之前选的v[id]而选择了新的v[l[id]]+v[r[id]]。同时相当于选择了缩点后的新节点,反之则没有[此时堆中节点值为为负数所以才不会选中,相当于新节点没选,也不需要更新左右节点值]。将新节点与左右两个坑中的节点比较作差丢入堆中。)

codes

#include<iostream>
#include<queue>
using namespace std;
const int maxn = 5e5+10;
struct node{
    int id, val;
    node(int id, int val):id(id),val(val){}
    bool operator < (const node & b)const{return val<b.val;}
};
priority_queue<node>q;
int l[maxn], r[maxn], data[maxn], ok[maxn];
int main(){
    int n,k;  cin>>n>>k;
    for(int i = 1; i <= n; i++){
        cin>>data[i];  q.push(node(i,data[i]));
        l[i] = i-1, r[i] = i+1;
    }
    r[0] = 1, l[n+1] = n;
    long long ans = 0;
    for(int i = 1; i <= k; i++){
        while(ok[q.top().id])q.pop();
        node t = q.top();  q.pop();
        if(t.val < 0)break;
        ans += t.val;
        int x = t.id;//缩点
        data[t.id] = data[l[t.id]]+data[r[t.id]]-data[t.id];//如果这个>0,下次还会被种到的
        ok[l[t.id]] = 1; ok[r[t.id]] = 1;
        l[t.id] = l[l[t.id]]; r[l[t.id]] = t.id;
        r[t.id] = r[r[t.id]]; l[r[t.id]] = t.id;
        q.push(node(x,data[t.id]));
    }
    cout<<ans<<'\n';
    return 0;
}
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

文章来源: gwj1314.blog.csdn.net,作者:小哈里,版权归原作者所有,如需转载,请联系作者。

原文链接:gwj1314.blog.csdn.net/article/details/81501466

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。