传送门


解题思路

第一眼的贪心策略:每次都选最大的。

但是——不正确!

因为选了第i个树,第i-1和i-1棵树就不能选了。所以,要有一个反悔操作。

选了第i个后,我们就把a[i]的值更新为a[l[i]]+a[r[i]]-a[i]。

然后这样如果发现选i-1和i+1更优时,再次加上a[i],结果就变成了a[i]+a[l[i]]+a[r[i]]-a[i]=a[l[i]]+a[r[i]]。

然后这时再更新l[i]和r[i],把左边和右边两个节点删去。

因为每一次会比上一次多种一棵,所以循环k次,求一个ans即为答案。

也许会有疑问,当i-1或i+1是负数时,不选这个负数明显更优,但是a[i-1]+a[i+1]是包含了这个负数的。

其实我们考虑,当有一个是负数,且a[i-1]+a[i+1]>a[i]时,很显然是另一个正数大于a[i],而这个正数一定会比i这棵树先种,所以不必考虑这种情况。

最后,当现在操作的最大利益已经是负数或零了,可以直接break掉,因为树是最大k棵。

AC代码

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<queue>
  4. using namespace std;
  5. const int maxn=;
  6. int n,k,l[maxn],r[maxn],a[maxn],vis[maxn];
  7. long long ans;
  8. struct node{
  9. int id,value;
  10. bool operator < (const node &x)const{
  11. return value<x.value;
  12. }
  13. node(int a,int b):id(a),value(b){}
  14. };
  15. priority_queue<node> q;
  16. int main(){
  17. cin>>n>>k;
  18. for(int i=;i<=n;i++){
  19. scanf("%d",&a[i]);
  20. l[i]=i-;
  21. r[i]=i+;
  22. q.push(node(i,a[i]));
  23. }
  24. r[]=;
  25. l[n+]=n;
  26. while(k--){
  27. while(vis[q.top().id]){
  28. q.pop();
  29. }
  30. node x=q.top();
  31. q.pop();
  32. if(x.value<=) break;
  33. ans+=x.value;
  34. int id=x.id;
  35. vis[l[id]]=vis[r[id]]=;
  36. a[id]=a[l[id]]+a[r[id]]-a[id];
  37. x.value=a[id];
  38. r[l[l[id]]]=id;
  39. l[r[r[id]]]=id;
  40. l[id]=l[l[id]];
  41. r[id]=r[r[id]];
  42. q.push(x);
  43. }
  44. cout<<ans;
  45. return ;
  46. }

洛谷 P1484 种树(优先队列,贪心,链表)的更多相关文章

  1. 洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心)

    洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/132 ...

  2. [洛谷P1484] 种树

    题目类型:堆+贪心 传送门:>Here< 题意:有\(N\)个坑,每个坑可以种树,且获利\(a[i]\)(可以为负).任何相邻两个坑里不能都种树,问在最多种\(K\)棵树的前提下的最大获利 ...

  3. 洛谷 P1484 种树

    题目描述 cyrcyr今天在种树,他在一条直线上挖了n个坑.这n个坑都可以种树,但为了保证每一棵树都有充足的养料,cyrcyr不会在相邻的两个坑中种树.而且由于cyrcyr的树种不够,他至多会种k棵树 ...

  4. 洛谷P1250种树(贪心)

    题目描述 一条街的一边有几座房子.因为环保原因居民想要在路边种些树.路边的地区被分割成块,并被编号成1..N.每个部分为一个单位尺寸大小并最多可种一棵树.每个居民想在门前种些树并指定了三个号码B,E, ...

  5. 洛谷 P1484 种树 题解

    题面 这是一道标准的带反悔贪心: 利用大根堆来维护最大值: 当选择了num[i]后,反悔了,反之选择选了num[i-1]和num[i+1]时获利便增加了num[i-1]+num[i+1]-num[i] ...

  6. Guard Duty (medium) Codeforces - 958E2 || (bzoj 2151||洛谷P1792) 种树 || 编译优化

    https://codeforces.com/contest/958/problem/E2 首先求出N个时刻的N-1个间隔长度,问题就相当于在这些间隔中选K个数,相邻两个不能同时选,要求和最小 方法1 ...

  7. 【洛谷】【堆+贪心】P1484 种树

    [题目描述:] cyrcyr今天在种树,他在一条直线上挖了n个坑.这n个坑都可以种树,但为了保证每一棵树都有充足的养料,cyrcyr不会在相邻的两个坑中种树.而且由于cyrcyr的树种不够,他至多会种 ...

  8. 洛谷P1996 约瑟夫问题【链表】

    题目:https://www.luogu.org/problemnew/show/P1996 题意: 约瑟夫环.每次取出第m个,第2m个...... 思路: 链表维护.[感觉很少有用到链表.]非常经典 ...

  9. 洛谷P4064 [JXOI2017]加法(贪心 差分)

    题意 题目链接 Sol 这题就是一个很显然的贪心... 首先二分一个答案,然后check是否可行.check的时候我们需要对每个位置\(i\),维护出所有左端点在\(i\)左侧,右端点在\(i\)右侧 ...

随机推荐

  1. NOIP2016提高A组模拟10.15总结

    第一题,就是将原有的式子一步步简化,不过有点麻烦,搞了很久. 第二题,枚举上下边界,维护一个单调队列,二分. 比赛上没有想到,只打了个暴力,坑了80分. 第三题,贪心,最后的十多分钟才想到,没有打出来 ...

  2. jsp三种注释方法

    HTML注释(输出注释):指在客户端查看源代码时能看见注释.例如, <!-- this is an html comment.it will show up int the response. ...

  3. 19. ClustrixDB 执行计划解读

    EXPLAIN语句用于显示ClustrixDB查询优化器(也称为Sierra)如何执行INSERT.SELECT.UPDATE和DELETE语句.EXPLAIN的输出有三列: Operation - ...

  4. idea编写第一个springboot程序

    1. 创建一个 springboot 项目 使用 idea 创建的基本步骤: 2. 加入父级,起步依赖 pom.xml文件内容: <?xml version="1.0" en ...

  5. ps -aux显示信息COMMAND不全

    ps -aux结果: ps -auxwww结果:

  6. Redis实战(十二)Redis实现分布式锁

    序言 SET my_key my_value NX PX milliseconds 资料 如何优雅地用Redis实现分布式锁?

  7. python3学习笔记(二):Python初识

    一.算法 在开始认真地编程之前,首先来解释下什么是计算机程序设计.简单地说,它就是告诉计算机要做什么.计算机可以做很多事情,但是它不会自己思考,需要我们告诉它具体细节,并且使用计算机能够理解的语言把算 ...

  8. C# walls

    在学习C#的阶段中,我们一点一点的往前爬, 此代码需要添加selenium ,和 获取 引用. using Ivony.Html.Parser; using Ivony.Html; using Ope ...

  9. http三次握手,四次挥手

    本文经过借鉴书籍资料.他人博客总结出的知识点,欢迎提问 序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生:给字节编上序号后 ...

  10. 《Effective Java》读书笔记 - 5.泛型

    Chapter 5 Generics Item 23: Don't use raw types in new code 虽然你可以把一个List<String>传给一个List类型(raw ...