这道题目还是比较简单的

首先题目的意思就让我们很轻易地想到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 种树的更多相关文章

  1. P1484 种树

    P1484 种树 题意: 在n个数中选出至多k个数,且两两不相邻,并使所选数的和最大. n<=500000  思路 先建一个堆,把所有点扔进去,当取出队首元素时累加到答案时,把它和它左右两个点一 ...

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

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

  3. luogu P1250 种树

    我来总结一下最常用的两种办法 1.贪心 2.差分约束 那么我们先来讲,贪心版<种树> 大家可能知道有一个题和这个类似,那个是钉钉子而这个是种树 我们可以借用钉钉子的思路来想,首先这个是让你 ...

  4. 洛谷 P1484 种树

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

  5. [洛谷P1484] 种树

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

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

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

  7. Luogu 1484 种树

    Luogu 1792 算是双倍经验. 我们考虑对于一个点,我们要么选它,要么选它周围的两个点. 所以我们考虑用一个堆来维护,每次从堆顶取出最大值之后我们把它的权值记为:它左边的权值加上它右边的权值减去 ...

  8. P1484 种树——数据结构优先队列

    种了一下午的树,终于给搞明白了((多谢各位大神的题解)(题解就不能讲清楚点吗(看不见看不见))): 你有k个树,你可以种在一条直线上,每个位置都有一个价值,如果你把树种在这里就可以获得这个价值,但是条 ...

  9. 题解 P1484 种树

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

随机推荐

  1. RecyclerView 下拉刷新和加载更多

    一.SwipeRefreshLayout实现下拉刷新 1.方法API: setOnRefreshListener(OnRefreshListener):添加下拉刷新监听器 setRefreshing( ...

  2. 用例设计之APP用例覆盖准则

    基本原则 本文主要讨论APP功能用例的覆盖,基本原则: 用户场景闭环(从哪来到哪去) 遍历所有的实现逻辑路径 需求点覆盖 覆盖维度 APP功能用例设计主要使用传统的黑盒用例设计方法.同时,作为移动AP ...

  3. 字节顺序标记BOM

    最近,从numbers导出的csv文件,导入excel后,出现中文乱码问题.网上查询后,发现是numbers导出的csv默认是utf-8无BOM的,使用sublimText3打开,另存为utf-8wi ...

  4. Apache2启动错误Could not reliably determine the server's fully qualified domain name

    错误情况: AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using ...

  5. sql server 日期时间与字符串的转换

    一.sql server日期时间函数Sql Server中的日期与时间函数 1.  当前系统日期.时间     select getdate()  2. dateadd  在向指定日期加上一段时间的基 ...

  6. MySQL客户端连接方式

    MySQL连接方式MySQL除了最常见的TCP连接方式外,还提供SOCKET(LINUX默认连接方式).PIPE和SHARED MEMORY连接方式.各连接方式的服务器.客户端启动选项,及连接默认值见 ...

  7. JSP中文乱码问题终极解决方案

    在介绍方法之前我们首先应该清楚具体的问题有哪些,笔者在本博客当中论述的JSP中文乱码问题有如下几个方面:页面乱码.参数乱码.表单乱码.源文件乱码.下面来逐一解决其中的乱码问题. 一.JSP页面中文乱码 ...

  8. 转:ASP.NET前台代码绑定后台变量方法总结

    经常会碰到在前台代码中要使用(或绑定)后台代码中变量值的问题.一般有<%= str%>和<%# str %>两种方式,这里简单总结一下.如有错误或异议之处,敬请各位指教. 一方 ...

  9. StringBuffer&StringBuilder类

    0. 说明 1. 总体说明 当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类. 和 String 类不同的是,StringBuffer 和 String ...

  10. Linux nmap命令详解

    nmap,也就是Network Mapper,是Linux下的网络扫描和嗅探工具包. nmap是在网络安全渗透测试中经常会用到的强大的扫描器.功能之强大,不言而喻.下面介绍一下它的几种扫描命令.具体的 ...