若想要深入学习反悔贪心,传送门


Description:

有 \(n\) 个位置,每个位置有一个价值。有 \(m\) 个树苗,将这些树苗种在这些位置上,相邻位置不能都种。求可以得到的最大值或无解信息。

Method

先判断无解的情况,我们显然可以发现,若 \(n<\frac{2}{m}\) ,则是不能在合法的条件下种上 \(m\) 棵树的,故按题意输出Error!即可。

假如有解的话,我们可以很轻松的推出贪心策略:在合法的情况下选择最大的价值。

显然上面的策略是错误的,我们选择了最大价值的点,相邻的两个点就不能选,而选择相邻两个点得到的价值可能更大。

考虑如何设计反悔策略。

我们同样用差值来达到反悔的目的。假设有 \(A\) ,\(B\) ,\(C\) ,\(D\) 四个相邻的点(如图)。

\(A\) 点的价值为 \(a\) ,其他点同理。若:

\[a+c>b+d
\]

则:

\[a+c-b>d
\]

假如我们先选了 \(B\) 点,我们就不能选 \(A\) 和 \(C\) 两点,这显然是不对的,但我们可以新建一个节点 \(P\) , \(P\) 点的价值为 \(a+c-b\) ,再删去 \(B\) 点。(如图,红色的是删去的点,橙色的新建的点)

下一次选择的点是 \(P\) 的话,说明我们反悔了(即相当于 \(B\) 点没有选),可以保证最后的贪心最优解是全局最优解。

如何快速插入 \(P\) 点和找出是否选择 \(P\) 点呢?我们可以使用双向链表和小根堆,使得最终在 \(O(n\log n)\) 的时间复杂度下快速求出全局最优解。

Code:

#include<bits/stdc++.h>
#define int long long
#define Maxn 2000010
using namespace std;
inline void read(int &x)
{
int f=1;x=0;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
x*=f;
}
int n,m;
int w[Maxn],lft[Maxn],rgh[Maxn];
struct node
{
int val,id;
bool operator <(const node &n) const
{
return val<n.val;
}
};
priority_queue<node>qu;
int ind,ans=0;
int vis[Maxn];
signed main()
{
read(n),read(m);
ind=n;
if(n/2<m)
{
puts("Error!");
return 0;
}
for(int i=1;i<=n;i++)
{
read(w[i]);
node tmp;
tmp.id=i;
tmp.val=w[i];
qu.push(tmp);
if(i==1)
{
lft[i]=n;
rgh[i]=i+1;
}else if(i==n)
{
lft[i]=i-1;
rgh[i]=1;
}else
{
lft[i]=i-1;
rgh[i]=i+1;
}
}
for(int i=1;i<=m;i++)
{
while(vis[qu.top().id]) qu.pop();
int id=qu.top().id;
int val=qu.top().val;
qu.pop();
ans+=val;
ind++;
vis[lft[id]]=vis[rgh[id]]=1;
lft[rgh[rgh[id]]]=ind;rgh[lft[lft[id]]]=ind;
lft[ind]=lft[lft[id]];rgh[ind]=rgh[rgh[id]];
w[ind]=w[lft[id]]+w[rgh[id]]-val;
int newid=ind;
int newval=w[ind];
node tmp;
tmp.id=newid;
tmp.val=newval;
qu.push(tmp);
}
printf("%lld\n",ans);
return 0;
}

Warning:

  • 一定要记录这个点选没有选过,假如已经选过了,就从堆中丢出去;

  • 1与 \(n\) 是相邻的,一定要特判一下;

  • 双向链表一定不要写挂了;

  • 一定要先将新建的点的价值存入一开始的价值数组,再丢进堆里;(卡在45卡了好久)

  • index是关键字,一定不要使用。(我成功CE了一次)

BZOJ2151/洛谷P1792 题解的更多相关文章

  1. Guard Duty (medium) Codeforces - 958E2 || (bzoj 2151||洛谷P1792) 种树 || 编译优化

    https://codeforces.com/contest/958/problem/E2 首先求出N个时刻的N-1个间隔长度,问题就相当于在这些间隔中选K个数,相邻两个不能同时选,要求和最小 方法1 ...

  2. [洛谷P3376题解]网络流(最大流)的实现算法讲解与代码

    [洛谷P3376题解]网络流(最大流)的实现算法讲解与代码 更坏的阅读体验 定义 对于给定的一个网络,有向图中每个的边权表示可以通过的最大流量.假设出发点S水流无限大,求水流到终点T后的最大流量. 起 ...

  3. 洛谷P5759题解

    本文摘自本人洛谷博客,原文章地址:https://www.luogu.com.cn/blog/cjtb666anran/solution-p5759 \[这道题重在理解题意 \] 选手编号依次为: \ ...

  4. 关于三目运算符与if语句的效率与洛谷P2704题解

    题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图.在每一格平原地形上最 ...

  5. c++并查集配合STL MAP的实现(洛谷P2814题解)

    不会并查集的话请将此文与我以前写的并查集一同食用. 原题来自洛谷 原题 文字稿在此: 题目背景 现代的人对于本家族血统越来越感兴趣. 题目描述 给出充足的父子关系,请你编写程序找到某个人的最早的祖先. ...

  6. 洛谷P2607题解

    想要深入学习树形DP,请点击我的博客. 本题的DP模型同 P1352 没有上司的舞会.本题的难点在于如何把基环树DP转化为普通的树上DP. 考虑断边和换根.先找到其中的一个环,在上面随意取两个点, 断 ...

  7. 【洛谷】题解 P1056 【排座椅】

    题目链接 因为题目说输入保证会交头接耳的同学前后相邻或者左右相邻,所以一对同学要分开有且只有一条唯一的通道才能把他们分开. 于是可以吧这条通道累加到一个数组里面.应为题目要求纵列的通道和横列的通道条数 ...

  8. [洛谷P1792][国家集训队]种树

    题目大意:给出由$n$个数组成的环,取某个数就可以得到它的分数,相邻的两个数不能同时取.问取$m$个数可以得到的最大分数. 题解:建一个大根堆,贪心取,每个点记录前驱后继,取一个点就把前驱后继设成不能 ...

  9. 洛谷P3572题解

    这道题实在是一道 毒瘤 题,太坑爹了.那个写 \(deque\) 的题解亲测只有80分,原因 不言而明 ,这道题居然 丧心病狂 到 卡STL . 好了,不吐槽了,进入正题 题目分析: 这是一道十分 简 ...

随机推荐

  1. VS 安装resharper 后 无法进行UnitTest

    Vs安装 Resharper后,无法进行单元测试,发现报错提示信息如下: ignored test-case is missing. rebuild the project and try again ...

  2. 自定义HTTP消息拦截

    /// <summary> /// HTTP消息拦截器 /// </summary> public class RequestHandler : DelegatingHandl ...

  3. Mybatis 复习

    概述 mybatis 是一个用java编写的持久层框架, 它封装了jdbc操作的很多细节,使开发者只需要关注sql语句本身,而无需关注注册驱动,创建连接等繁杂过程,它使用了ORM思想实现了结果 集的封 ...

  4. Java基础篇(中)

    4.Java 关键字 下面列出了 Java 关键字.这些保留字不能用于常量.变量.和任何标识符的名称. 类别 关键字 说明 访问控制 private 私有的 protected 受保护的 public ...

  5. Socker编程之TCP

    一:TCP介绍 TCP协议,传输控制协议(英语:Transmission Control Protocol,缩写为 TCP)是一种面向连接的.可靠的.基于字节流的传输层通信协议,由IETF的RFC 7 ...

  6. Samba + DLAN 实现电视机播放电脑文件

    用SMB功能——简单二步让电视访问电脑文件http://tieba.baidu.com/p/5330683066 DLNA怎么用?简单三步实现电脑电视DLNA互联!https://news.znds. ...

  7. Nginx学习(二)

    ------------恢复内容开始------------ Nginx配置文件 主配置文件结构:四部分 main block:主配置段,既全局配置段,对Http,mail都有效 event{ }事件 ...

  8. Echarts实现Excel趋势线和R平方计算思路

    测试数据 [19550, 7.1 ],[22498, 8.44 ],[25675, 9.56 ],[27701, 10.77],[29747, 11.5 ],[32800, 12.27],[34822 ...

  9. es聚合后排序

    注意: es版本至少6.1以上 语句: GET 76/sessions/_search { "size": 0, "query": { "bool&q ...

  10. The Preliminary Contest for ICPC Asia Nanjing 2019 H. Holy Grail

    题目链接:https://nanti.jisuanke.com/t/41305 题目说的很明白...只需要反向跑spfa然后输入-dis,然后添-dis的一条边就好了... #include < ...