Luogu P1484 种树
这道题目还是比较简单的
首先题目的意思就让我们很轻易地想到DP
我们设f[i][j]表示前i个坑中种j棵树的最大利益,则有:
f[i][j]=max(f[i-1][j],f[i-2][j-1]+a[i])
然而对于本题的数据范围之能得50pts
要A掉的话还是要动一些脑子的
我们先从小的情况开始讨论:
当k=1时,我们只需要找一个最大的收益即可(当然全负就不要找了)
当k=2时,我们先挑选一个最大的,若接下来最大的不是这个数两侧的数,那就区接下来最大的数即可
当k=2时,当然可能会有情况是选这两个数相邻的两个数(当然也只有这种情况)。表述得清楚一些就是若第一次选了a[i],除非最优解是a[i-1]+a[i+1],否则都是上面的选法最优
以此我们发现对于已经被选择的a[i],a[i-1],a[i+1]要么同时被选,要么同时落选
因此我们开一个大根堆,每次取出a[i]之后把它的值累加至ans后,将a[i]的值改成a[pre[i]]+a[nxt[i]]-a[i] (这里的pre[i]表示i的前驱,nxt[i]表示i的后继,刚开始就分别是i-1,i+1)
为什么呢,因为我们想一下,这样就给了程序一个返回的机会,此时当你选择了新的a[i]时,其实就是选择了原来的a[pre[i]]和a[nxt[i]]
然后开一个STL堆即可水过
CODE
#include<cstdio>
#include<queue>
using namespace std;
const int N=500005;
struct node
{
int v,num;
bool operator <(const node &s) const
{
return s.v>v;
}
};
priority_queue <node> big;
int a[N],pre[N],nxt[N],n,k,tot;
bool vis[N];
long long ans;
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch=tc(); int flag=1;
while (ch<'0'||ch>'9') { if (ch=='-') flag=-1; ch=tc(); }
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
x*=flag;
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
register int i;
read(n); read(k);
for (i=1;i<=n;++i)
read(a[i]),pre[i]=i-1,nxt[i]=i+1,big.push((node){a[i],i});
nxt[0]=1; pre[n+1]=n;
while (tot<k)
{
while (vis[big.top().num]) big.pop();
node p=big.top(); big.pop();
if (p.v<0) break; ++tot; ans+=p.v;
p.v=a[p.num]=a[pre[p.num]]+a[nxt[p.num]]-a[p.num];
vis[pre[p.num]]=vis[nxt[p.num]]=1;
pre[p.num]=pre[pre[p.num]]; nxt[pre[p.num]]=p.num;
nxt[p.num]=nxt[nxt[p.num]]; pre[nxt[p.num]]=p.num;
big.push(p);
}
printf("%lld",ans);
return 0;
}
Luogu P1484 种树的更多相关文章
- P1484 种树
P1484 种树 题意: 在n个数中选出至多k个数,且两两不相邻,并使所选数的和最大. n<=500000 思路 先建一个堆,把所有点扔进去,当取出队首元素时累加到答案时,把它和它左右两个点一 ...
- 洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心)
洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/132 ...
- luogu P1250 种树
我来总结一下最常用的两种办法 1.贪心 2.差分约束 那么我们先来讲,贪心版<种树> 大家可能知道有一个题和这个类似,那个是钉钉子而这个是种树 我们可以借用钉钉子的思路来想,首先这个是让你 ...
- 洛谷 P1484 种树
题目描述 cyrcyr今天在种树,他在一条直线上挖了n个坑.这n个坑都可以种树,但为了保证每一棵树都有充足的养料,cyrcyr不会在相邻的两个坑中种树.而且由于cyrcyr的树种不够,他至多会种k棵树 ...
- [洛谷P1484] 种树
题目类型:堆+贪心 传送门:>Here< 题意:有\(N\)个坑,每个坑可以种树,且获利\(a[i]\)(可以为负).任何相邻两个坑里不能都种树,问在最多种\(K\)棵树的前提下的最大获利 ...
- 【洛谷】【堆+贪心】P1484 种树
[题目描述:] cyrcyr今天在种树,他在一条直线上挖了n个坑.这n个坑都可以种树,但为了保证每一棵树都有充足的养料,cyrcyr不会在相邻的两个坑中种树.而且由于cyrcyr的树种不够,他至多会种 ...
- Luogu 1484 种树
Luogu 1792 算是双倍经验. 我们考虑对于一个点,我们要么选它,要么选它周围的两个点. 所以我们考虑用一个堆来维护,每次从堆顶取出最大值之后我们把它的权值记为:它左边的权值加上它右边的权值减去 ...
- P1484 种树——数据结构优先队列
种了一下午的树,终于给搞明白了((多谢各位大神的题解)(题解就不能讲清楚点吗(看不见看不见))): 你有k个树,你可以种在一条直线上,每个位置都有一个价值,如果你把树种在这里就可以获得这个价值,但是条 ...
- 题解 P1484 种树
题目 传送门 cyrcyr今天在种树,他在一条直线上挖了 n 个坑. 这n个坑都可以种树,但为了保证每一棵树都有充足的养料,cyrcyr不会在相邻的两个坑中种树. 而且由于cyrcyr的树种不够,他至 ...
随机推荐
- 2018-10-17 22:20:39 c language
2018-10-17 22:20:39 c language C语言中的空白符 空格.制表符.换行符等统称为空白符,它们只用来占位,并没有实际的内容,也显示不出具体的字符. 制表符分为水平制表符和垂 ...
- [Java] 用 Comparator 实现排序
最近正好用到Comparator,发现能对不同类型的对象进行排序(当然排序依据还是基本类型),也不用自己实现排序算法,用起来很方便,所以简单记录一下. 本文地址:http://www.cnblogs. ...
- Java web 开发填坑记 2 -如何正确的创建一个Java Web 项目
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/72566261 本文出自[赵彦军的博客] Java web 开发填坑记 1-如何正确 ...
- spring-quartz定时任务初探
最近有关定时任务的需求还蛮多的,我这里呢用的是最简单的用法,后续了解更深层次的用法来优化目前的代码. 首先就是引入相关jar quartz-1.6.4.jar spring的jar就不说了 接 ...
- 【python】python之tuple元组
tuple特性 python的tuple与列表类似,不同之处在于tuple的元素不能修改. tuple使用小括号,列表使用方括号. tuple创建很简单,只需要在括号中添加元素,并使用逗号隔开即可. ...
- python基础一数据类型之字典
摘要: python基础一数据类型之一字典,这篇主要讲字典. 1,定义字典 2,字典的基础知识 3,字典的方法 1,定义字典 1,定义1个空字典 dict1 = {} 2,定义字典 dict1 = d ...
- vc使用jsoncpp头文件冲突问题
编译时出现 1>d:\program files (x86)\microsoft visual studio 9.0\vc\include\xdebug(32) : warning C4229: ...
- skimage 安装和子模块
平台:Windows 10 1.安装anaconda anaconda是python环境的集成安装软件,建议安装2.7版本的python 2.安装skimage 打开windows的命令提示符: 输 ...
- 【Python】os.path.isfile()的使用方法汇总
方法一: # -*- coding:utf-8 -*- import os import sys from uiautomator import device as d filepath = r'E: ...
- 【python27】猜随机数的小游戏
游戏规则: 猜一个随机数,如果猜对了就给出相应的猜成功提示语(自定义文字),如果猜大或者是猜小了,给出对应的提示,但总的猜次数为三次,每猜错一次重新猜时,给用户提示所剩余的猜次数 实现如下: # -* ...