BZOJ_2151_种树_贪心+堆

Description

A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树。园林部门得到指令后,初步规划出n个种树的位置,顺时针编号1到n。并且每个位置都有一个美观度Ai,如果在这里种树就可以得到这Ai的美观度。但由于A城市土壤肥力欠佳,两棵树决不能种在相邻的位置(i号位置和i+1号位置叫相邻位置。值得注意的是1号和n号也算相邻位置!)。最终市政府给园林部门提供了m棵树苗并要求全部种上,请你帮忙设计种树方案使得美观度总和最大。如果无法将m棵树苗全部种上,给出无解信息。

Input

输入的第一行包含两个正整数n、m。第二行n个整数Ai。

Output

输出一个整数,表示最佳植树方案可以得到的美观度。如果无解输出“Error!”,不包含引号。

Sample Input

【样例输入1】
7 3
1 2 3 4 5 6 7
【样例输入2】
7 4
1 2 3 4 5 6 7

Sample Output

【样例输出1】
15

【样例输出2】
Error!
【数据规模】
对于全部数据:m<=n;
-1000<=Ai<=1000
N的大小对于不同数据有所不同:
数据编号 N的大小 数据编号 N的大小
1 30 11 200
2 35 12 2007
3 40 13 2008
4 45 14 2009
5 50 15 2010
6 55 16 2011
7 60 17 2012
8 65 18 199999
9 200 19 199999
10 200 20 200000


首先有$O(n^2)$的暴力显然,于是你这道题就可以拿到70分..

我们考虑贪心,每次挑最大的那个删除,同时把左右的也删除,这显然是错的,因为可能有3 5 4,我选3+4要比选5更优。

但是5仍然非常重要,因为你需要同时选2个才可以不选这个5。

于是有了另外一种可以反悔的贪心的思路:每次找最大的并把它两边删除,把这个数修改成它的权值减去两边的权值,其中找最大的用一个堆来维护,找两边的数用链表。

这样就是对的了,因为这相当于我每次都会取出一个数,并且保证每次对答案的贡献增加的最多。

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std;
#define N 200050
int n,m,a[N],kill[N];
struct node {
int v,p;
node() {}
node(int v_,int p_) :
v(v_),p(p_) {}
inline bool operator < (const node &x) const {
return v<x.v;
}
};
priority_queue<node>q;
int L[N],R[N];
void del(int x) {
L[R[x]]=L[x];
R[L[x]]=R[x];
}
int main() {
// freopen("tree.in","r",stdin);
// freopen("tree.out","w",stdout);
scanf("%d%d",&n,&m);
if(m>n/2) {
puts("Error!"); return 0;
}
int i;
for(i=1;i<=n;i++) {
scanf("%d",&a[i]);
q.push(node(a[i],i)); L[i]=i-1; R[i]=i+1;
}
R[n]=1; L[1]=n; int ans=0;
for(i=1;i<=m;i++) {
while(!q.empty()&&kill[q.top().p]) q.pop();
node t=q.top(); q.pop();
kill[L[t.p]]=kill[R[t.p]]=1;
a[t.p]=a[L[t.p]]+a[R[t.p]]-a[t.p];
del(L[t.p]); del(R[t.p]);
ans+=t.v;
q.push(node(a[t.p],t.p));
}
printf("%d\n",ans);
}

BZOJ_2151_种树_贪心+堆+链表的更多相关文章

  1. BZOJ2151 种树(贪心+堆+链表/wqs二分+动态规划)

    dp容易想到,但没法进一步优化了. 考虑贪心,每次选出价值最大的物品.但这显然是不对的因为会影响其他物品的选择. 于是考虑加上反悔操作.每次选出一个物品后,将其相邻两物品删除,再将原物品价值变为相邻两 ...

  2. BZOJ_2006_[NOI2010]超级钢琴_贪心+堆+ST表

    BZOJ_2006_[NOI2010]超级钢琴_贪心+堆+ST表 Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐 ...

  3. BZOJ_1029_ [JSOI2007]建筑抢修_贪心+堆

    BZOJ_1029_ [JSOI2007]建筑抢修_贪心+堆 Description 小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者.但是 ...

  4. 【BZOJ 2151】 2151: 种树 (贪心+堆+双向链表)

    2151: 种树 Description A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树.园林部门得到指令后,初步规划出n个种树的位置,顺时针编号1到n.并且每个 ...

  5. bzoj 2151: 种树【贪心+堆】

    和数据备份差不多 设二元组(i,a[i]),开一个大根堆把二元组塞进去,以len排序,每次取出一个二元组 因为单纯的贪心是不行的,所以设计一个"反悔"操作. 记录二元组的前驱pr后 ...

  6. [bzoj2288][pojChallenge]生日礼物【贪心+堆+链表】

    题目描述 ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1, A2, -, AN. 她被允许选择不超过 M 个连续的部分作为自己的生日礼物. 自然地,ftiasch想要知 ...

  7. [luogu3620][APIO/CTSC 2007]数据备份【贪心+堆+链表】

    题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家中尽享计算机游戏 ...

  8. BZOJ 2288: 【POJ Challenge】生日礼物 贪心 + 堆 + 链表

    好像是模拟费用流 Code: #include <bits/stdc++.h> #define setIO(s) freopen(s".in","r" ...

  9. [BZOJ2288&BZOJ1150]一类堆+链表+贪心问题

    今天我们来介绍一系列比较经典的堆+链表问题.这类问题的特点是用堆选取最优解,并且通过一些加减操作来实现"反悔". 在看题之前,我们先来介绍一个神器:手写堆. 手写堆的一大好处就是可 ...

随机推荐

  1. angularjs学习笔记之一

    directive 通过AngularJS模块API中的.directive()方法,我们可以通过传入一个字符串和一个函数来 注册一个新指令.其中字符串是这个指令的名字,指令名应该是驼峰命名风格的,函 ...

  2. JTA 分布式事务

    什么是JTA - 2009-07-25 18:31:06|  分类: 技术文章|举报|字号 订阅     什么是JTA? Java Transaction API(Java事务API) (JTA)Ja ...

  3. [总结] 二维ST表及其优化

    二维 \(\mathcal{ST}\) 表,可以解决二维 \(\mathcal{RMQ}\) 问题.这里不能带修改,如果要修改,就需要二维线段树解决了. 上一道例题吧 ZOJ2859 类比一维 \(\ ...

  4. Web前端文件上传进度的显示

    跟后台关系不大,主要是前端js实现,具体使用了XMLHttpRequest的ProgressEvent事件,可以参考MDN中的Using XMLHttpRequest https://develope ...

  5. 在cmd下运行Python脚本+如何使用Python Shell

    原文:https://blog.csdn.net/flyfrommath/article/details/77447587?locationNum=2&fps=1

  6. python笔记:#011#循环

    循环 目标 程序的三大流程 while 循环基本使用 break 和 continue while 循环嵌套 01. 程序的三大流程 在程序开发中,一共有三种流程方式: 顺序 -- 从上向下,顺序执行 ...

  7. (四)SpringBoot2.0基础篇- 多数据源,JdbcTemplate和JpaRepository

    在日常开发中,经常会遇到多个数据源的问题,而SpringBoot也有相关API:Configure Two DataSources:https://docs.spring.io/spring-boot ...

  8. java 字符串池【转】

    java 字符串池 java运行环境有一个字符串池.比如String str="abc"时,会首先查看字符串池中是否存在字符串"abc",如果存在则直接将&qu ...

  9. c语言中realloc()函数解析

    一.基本特性 1. realloc()函数可以重用或扩展以前用malloc().calloc()及realloc()函数自身分配的内存. 2. realloc()函数需两个参数:一个是包含地址的指针( ...

  10. Java(四、类和对象)

    Java 对象和类 Java作为一种面向对象语言.支持以下基本概念: 多态.继承.封装.抽象.类.对象.实例.方法.重载 对象 对象是类的一个实例(对象不是找个女朋友),有状态和行为.例如,一条狗是一 ...