bzoj 2151 种树 —— 思路+链表
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2151
先都放进堆里取最大的,但选了一个就不能选它两边的,所以可能不是最优,要有“反悔”的措施;
可以取出一个后把它两边的位置 l,r 在链表中删除,然后再加入一个元素 a[x] = a[l] + a[r] - a[x],如果日后选了这个元素,就表示“反悔”了,当初不选 x 而是同时选了两边的(同时选比只选一个或不选更优);
而此时这个 x 的两边实际上是 l-1 和 r+1,因为其实选的是 l,r,这点用链表删除和查询就可以体现,更何况两边也可能被这样合并过;
再记一个 vis 表示这个位置从堆里取出时能不能选了,和链表的删除一致;
因为每次取出都会增加一个选择的位置,所以取出 m 次即可。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int const xn=2e5+;
int n,m,a[xn],pr[xn],nt[xn],ans;
bool vis[xn];
struct N{
int v,id;
bool operator < (const N &y) const
{return v<y.v;}
};
priority_queue<N>q;
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
return f?ret:-ret;
}
void del(int x){nt[pr[x]]=nt[x]; pr[nt[x]]=pr[x];}
int main()
{
n=rd(); m=rd();
for(int i=;i<=n;i++)
{
a[i]=rd();
q.push((N){a[i],i});
}
if(n<*m){puts("Error!"); return ;}
for(int i=;i<n;i++)pr[i]=i-,nt[i]=i+;
pr[]=n; nt[]=; pr[n]=n-; nt[n]=;
for(int i=;i<=m;i++)
{
int x=q.top().id,w=q.top().v; q.pop();
while(vis[x])x=q.top().id,w=q.top().v,q.pop();
int l=pr[x],r=nt[x]; ans+=w;
del(l); del(r); vis[l]=; vis[r]=; a[x]=a[l]+a[r]-w;
q.push((N){a[x],x});
}
printf("%d\n",ans);
return ;
}
bzoj 2151 种树 —— 思路+链表的更多相关文章
- [bzoj 2151]种树(贪心)
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2151 分析:原型是bzoj 1150(CTSC 2007) 首先DP无法下手,想到贪心.想到贪 ...
- bzoj 2151 种树——贪心+后悔
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2151 似乎是半年+前讲过的.(然而看到的时候却不会了) 考虑贪心,限制就是不能选两边的.如果 ...
- 【刷题】BZOJ 2151 种树
Description A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树.园林部门得到指令后,初步规划出n个种树的位置,顺时针编号1到n.并且每个位置都有一个美观度 ...
- BZOJ 2151 种树(循环链表)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2151 [题目大意] 在一个长度为n的数字环中挑选m个不相邻的数字使得其和最大 [题解] ...
- 题解 bzoj 2151 种树
题意 传送门 手写堆大法好啊,题解貌似没有结构体堆的做法,思路有些像配对堆,关于配对堆请自行百度,因为本蒟蒻不会.. 以下是蒟蒻的做法:建立一个大根堆a维护最大价值里面存入它的编号以及价值.听说配对堆 ...
- BZOJ 2151 种树
贪心+priority_queue. #include<iostream> #include<cstdio> #include<cstring> #include& ...
- bzoj 2151: 种树【贪心+堆】
和数据备份差不多 设二元组(i,a[i]),开一个大根堆把二元组塞进去,以len排序,每次取出一个二元组 因为单纯的贪心是不行的,所以设计一个"反悔"操作. 记录二元组的前驱pr后 ...
- Guard Duty (medium) Codeforces - 958E2 || (bzoj 2151||洛谷P1792) 种树 || 编译优化
https://codeforces.com/contest/958/problem/E2 首先求出N个时刻的N-1个间隔长度,问题就相当于在这些间隔中选K个数,相邻两个不能同时选,要求和最小 方法1 ...
- 【BZOJ 2151】 2151: 种树 (贪心+堆+双向链表)
2151: 种树 Description A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树.园林部门得到指令后,初步规划出n个种树的位置,顺时针编号1到n.并且每个 ...
随机推荐
- 洛谷——P2733 家的范围 Home on the Range
P2733 家的范围 Home on the Range 题目背景 农民约翰在一片边长是N (2 <= N <= 250)英里的正方形牧场上放牧他的奶牛.(因为一些原因,他的奶牛只在正方形 ...
- Spring Boot集成Spring Data Reids和Spring Session实现Session共享(多个不同的应用共用一个Redis实例)
从Redis的Key入手,比如Spring Session在注解@EnableRedisHttpSession上提供了redisNamespace属性,只需要在这里设置不同的值即可,效果应该是这样的: ...
- paramiko使用exec_command执行rm -rf删除目录的坑
paramiko删除目录后的上传操作请参考步骤1.2.3的说明 try: ssh = SSHClient(ip,user) sftpClient = ssh.getSftpClient() outpu ...
- Hbase调用JavaAPI实现批量导入操作
将手机上网日志文件批量导入到Hbase中.操作步骤: 1.将日志文件(请下载附件)上传到HDFS中,利用hadoop的操作命令上传:hadoop fs -put input / 2.创建Hbase ...
- 关于Java基础的一些笔试题总结
针对近期腾讯.京东.网易等公司的笔试,遇到一些有关Java基础的问题,在此总结,希望能通过这几道经典问题题发散,举一反三,借此打牢基础!自己总结,望提出宝贵意见! 一.关于null的一道小题 先开开 ...
- 生活娱乐 360安全卫士和QQ大战
360安全卫士指控QQ侵犯用户隐私 [提要]9月26日晚上11点16分,安全软件商360在他们的论坛中发布了最新公告:<360安全卫士发布隐私保护器 专门曝光"窥私"软件&g ...
- C/C++知识要点2——STL中Vector、Map、Set容器的实现原理
1.Vector是顺序容器.是一个动态数组.支持随机存取.插入.删除.查找等操作,在内存中是一块连续的空间.在原有空间不够情况下自己主动分配空间.添加为原来的两倍.vector随机存取效率高,可是在v ...
- max-points-on-a-line——穷举
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. ...
- 简谈Java的join()方法(转)
join()是Thread类的一个方法.根据jdk文档的定义: public final void join()throws InterruptedException: Waits for this ...
- 8. Smarty3:模版中的内置函数
smarty3中对内置函数的修改比較大,加入了很多新的功能:变量声明.表达式,流程控制,函数.数组等.可是建议不要在模版中去使用过于复杂的逻辑,而是要尽量将一些程序设计逻辑写到PHP中,并在模版中採用 ...