洛谷 P1484 种树(优先队列,贪心,链表)
传送门
解题思路
第一眼的贪心策略:每次都选最大的。
但是——不正确!
因为选了第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代码
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
const int maxn=;
int n,k,l[maxn],r[maxn],a[maxn],vis[maxn];
long long ans;
struct node{
int id,value;
bool operator < (const node &x)const{
return value<x.value;
}
node(int a,int b):id(a),value(b){}
};
priority_queue<node> q;
int main(){
cin>>n>>k;
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
l[i]=i-;
r[i]=i+;
q.push(node(i,a[i]));
}
r[]=;
l[n+]=n;
while(k--){
while(vis[q.top().id]){
q.pop();
}
node x=q.top();
q.pop();
if(x.value<=) break;
ans+=x.value;
int id=x.id;
vis[l[id]]=vis[r[id]]=;
a[id]=a[l[id]]+a[r[id]]-a[id];
x.value=a[id];
r[l[l[id]]]=id;
l[r[r[id]]]=id;
l[id]=l[l[id]];
r[id]=r[r[id]];
q.push(x);
}
cout<<ans;
return ;
}
洛谷 P1484 种树(优先队列,贪心,链表)的更多相关文章
- 洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心)
洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/132 ...
- [洛谷P1484] 种树
题目类型:堆+贪心 传送门:>Here< 题意:有\(N\)个坑,每个坑可以种树,且获利\(a[i]\)(可以为负).任何相邻两个坑里不能都种树,问在最多种\(K\)棵树的前提下的最大获利 ...
- 洛谷 P1484 种树
题目描述 cyrcyr今天在种树,他在一条直线上挖了n个坑.这n个坑都可以种树,但为了保证每一棵树都有充足的养料,cyrcyr不会在相邻的两个坑中种树.而且由于cyrcyr的树种不够,他至多会种k棵树 ...
- 洛谷P1250种树(贪心)
题目描述 一条街的一边有几座房子.因为环保原因居民想要在路边种些树.路边的地区被分割成块,并被编号成1..N.每个部分为一个单位尺寸大小并最多可种一棵树.每个居民想在门前种些树并指定了三个号码B,E, ...
- 洛谷 P1484 种树 题解
题面 这是一道标准的带反悔贪心: 利用大根堆来维护最大值: 当选择了num[i]后,反悔了,反之选择选了num[i-1]和num[i+1]时获利便增加了num[i-1]+num[i+1]-num[i] ...
- Guard Duty (medium) Codeforces - 958E2 || (bzoj 2151||洛谷P1792) 种树 || 编译优化
https://codeforces.com/contest/958/problem/E2 首先求出N个时刻的N-1个间隔长度,问题就相当于在这些间隔中选K个数,相邻两个不能同时选,要求和最小 方法1 ...
- 【洛谷】【堆+贪心】P1484 种树
[题目描述:] cyrcyr今天在种树,他在一条直线上挖了n个坑.这n个坑都可以种树,但为了保证每一棵树都有充足的养料,cyrcyr不会在相邻的两个坑中种树.而且由于cyrcyr的树种不够,他至多会种 ...
- 洛谷P1996 约瑟夫问题【链表】
题目:https://www.luogu.org/problemnew/show/P1996 题意: 约瑟夫环.每次取出第m个,第2m个...... 思路: 链表维护.[感觉很少有用到链表.]非常经典 ...
- 洛谷P4064 [JXOI2017]加法(贪心 差分)
题意 题目链接 Sol 这题就是一个很显然的贪心... 首先二分一个答案,然后check是否可行.check的时候我们需要对每个位置\(i\),维护出所有左端点在\(i\)左侧,右端点在\(i\)右侧 ...
随机推荐
- Redis :Linux和Window查看版本号
一.Linux版本:查看服务端版本 **二者都可以** redis-server -v redis-server --version 查看客户端版本 **二者都可以** redis-cli -v re ...
- GO语言学习笔记5-defer的使用
1. 什么是defer defer是Go语言提供的一种用于注册延迟调用的机制:让函数或语句可以在当前函数执行完毕后(包括通过return正常结束或者panic导致的异常结束)执行. 2. defer的 ...
- docker-compose命令及yaml文件
Docker-compose常用命令 docker-compose up -d nginx 构建建启动nignx容器 docker-compose exec nginx bash 登录到nginx容器 ...
- maven项目使用自己创建的jar包--maven without test code
eclipse版本为2018-12(4.10.0) 1.创建一个jar包 首先自己建立了一个maven project,名为jweb.GAV坐标: <groupId>amberai< ...
- [模板] Kruskal算法 && 克鲁斯卡尔重构树
克鲁斯卡尔重构树 发现没把板子放上来... 现在放一下 克鲁斯卡尔算法的正确性是利用反证法证明的. 简要地说, 就是如果不加入当前权值最小的边 \(e_1\), 那么之后加入的边和这条边会形成一个环. ...
- H5 网站支付宝支付(前端部分)包含微信浏览器中的处理方法。
手机网站唤起支付宝支付: H5 网站实现支付宝支付是一个很常见的需求: 实现方式主要是在后台配置和预支付, 前端需要做的就是唤起 支付宝App 然后就可以输入密码支付. 这个其实难度很低, 主要就是在 ...
- sqli-labs(18)
开始挑战第十八关(Header Injection - Uagent field - Error based) 常见的HTTP注入点产生位置为[Referer].[X-Forwarded-For].[ ...
- Xdebug bad Zend API Version Number
I am having trouble upgrading xdebug for MAMP. I was running version 2.2.0 and there was a known iss ...
- python之设计模式的装饰器9步学习
在继承的基础上增加新功能,重载,重写区别 装饰器: 函数a说,我是装饰器啊,其他哪个函数顶着我,我就吃了谁,然后吐出来我的和你的返回结果 testng的UI自动化,@beforetest,@befor ...
- PTA编程总结三
7-1 抓老鼠啊~亏了还是赚了? (20 分) 某地老鼠成灾,现悬赏抓老鼠,每抓到一只奖励10元,于是开始跟老鼠斗智斗勇:每天在墙角可选择以下三个操作:放置一个带有一块奶酪的捕鼠夹(T),或者放置一块 ...