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

标签:题解

阅读体验:https://zybuluo.com/Junlier/note/1329957

题目链接地址:

洛谷P1484 种树

洛谷P3620 [APIO/CTSC 2007]数据备份(各大oj多倍经验)

照例吐槽

两道基本一模一样的题,只是第二道要差分顺便思维稍微向这边转化一下。。。

我觉得这两个题思维很不错啊!很\(Noip\ T2\)的样子。。。

话不多说将题解

贪心+堆优化

肯定一开始想到一个\(O(nk)\)的\(dp\)是吧,发现跑不过又优化不了。。。

那和\(dp\)最相近而且时间复杂度低的算法就是贪心了罗。。。

下面以洛谷P1484 种树为题目来讲,洛谷P3620 [APIO/CTSC 2007]数据备份的话自己\(yy\)改一下就过啦

不用想了,每次直接选最大值肯定是错误的。。。

那怎么办?贪心不是有后悔操作嘛!

我们还是直接贪心选最大的,考虑怎么后悔,是不是与选\(v[i]\)相对的就是选\(v[i-1],v[i+1]\),那么对于一次后悔,我们可以看做选了\(v[i]\)后,\(Ans+=v[i]\),并且后面我们又选了一个\(v[i-1]+v[i+1]-v[i]\),算一下发现最终就是\(Ans+=v[i+1]+v[i-1]\)是吧,所以我们可以考虑直接把\(v[i]\)的值修改了之后可能重新选一遍

那么怎么实现这些操作呢(口糊谁不会。。)

一般这种最大最小加东西删东西的就可以想到堆啦

考虑用一个大根堆来贪心,每次选出一个最大的元素,然后显然我们要把这个元素两边的元素标记为不能选是吧,那就标记一下呗(因为我们会修改\(v[i]\)的值,所以无所顾忌这两个东西是否还存在,有点难理解。。。)

然后我们发现当我们修改了元素的值之后,他影响到的左右是不同的,所以我们还需要一个可以支持动态修改左右元素的数据结构,显然的不就是双向链表嘛。。。

那就做完了

代码

压行永远是看代码的人的噩梦,写代码的人的幸福。。。

洛谷P1484 种树

#include<bits/stdc++.h>
#define il inline
#define rg register
#define ldb double
#define lst long long
#define rgt register int
#define N 500050
using namespace std;
const int Inf=1e9;
il int MAX(rgt x,rgt y){return x>y?x:y;}
il int MIN(rgt x,rgt y){return x<y?x:y;}
il int read()
{
int s=0,m=0;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')m=1;ch=getchar();}
while( isdigit(ch))s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return m?-s:s;
} int n,K;lst Ans;
int v[N],le[N],ri[N],vis[N];
struct NODE{int id,w;};
priority_queue<NODE> H;
bool operator<(const NODE&a,const NODE&b){return a.w<b.w;} int main()
{
n=read(),K=read();
for(rgt i=1;i<=n;++i)
{
v[i]=read(),le[i]=i-1,ri[i]=i+1;
H.push((NODE){i,v[i]});
}
for(rgt i=1,l,r;i<=K;++i)
{
while(!H.empty()&&vis[H.top().id])H.pop();
rg NODE tmp=H.top();H.pop();if(tmp.w<0)break;
Ans+=tmp.w,l=le[tmp.id],r=ri[tmp.id];
v[tmp.id]=v[l]+v[r]-v[tmp.id];
ri[le[l]]=ri[l],le[ri[l]]=le[l],le[l]=ri[l]=0;
ri[le[r]]=ri[r],le[ri[r]]=le[r],le[r]=ri[r]=0;
vis[l]=vis[r]=1,H.push((NODE){tmp.id,v[tmp.id]});
}return printf("%lld\n",Ans),0;
}

洛谷P3620 [APIO/CTSC 2007]数据备份

需要注意的是:因为变成了最小值,所以边界可能会减出负数,所以处理下边界。。。

#include<bits/stdc++.h>
#define il inline
#define rg register
#define ldb double
#define lst long long
#define rgt register int
#define N 100050
using namespace std;
const int Inf=1e9;
il int MAX(rgt x,rgt y){return x>y?x:y;}
il int MIN(rgt x,rgt y){return x<y?x:y;}
il int read()
{
int s=0,m=0;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')m=1;ch=getchar();}
while( isdigit(ch))s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return m?-s:s;
} int n,K;lst Ans;
int v[N],le[N],ri[N],vis[N];
struct LINE{int id,x;};
priority_queue<LINE> H;
bool operator<(const LINE&a,const LINE&b){return a.x>b.x;} int main()
{
n=read(),K=read();
for(rgt i=1;i<=n;++i)v[i]=read();
for(rgt i=1;i<n;++i)
{
v[i]=v[i+1]-v[i];
le[i]=i-1,ri[i]=i+1;
H.push((LINE){i,v[i]});
}v[0]=v[n]=Inf;
for(rgt i=1,l,r;i<=K;++i)
{
while(!H.empty()&&vis[H.top().id])H.pop();
rg LINE tmp=H.top();H.pop();
Ans+=tmp.x,l=le[tmp.id],r=ri[tmp.id];
v[tmp.id]=v[l]+v[r]-v[tmp.id];
ri[le[l]]=ri[l],le[ri[l]]=le[l],le[l]=ri[l]=0;
ri[le[r]]=ri[r],le[ri[r]]=le[r],le[r]=ri[r]=0;
vis[l]=vis[r]=1,H.push((LINE){tmp.id,v[tmp.id]});
}return printf("%lld\n",Ans),0;
}

洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心)的更多相关文章

  1. 洛谷 P3620 [APIO/CTSC 2007]数据备份 解题报告

    P3620 [APIO/CTSC 2007]数据备份 题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同 ...

  2. P3620 [APIO/CTSC 2007]数据备份

    P3620 [APIO/CTSC 2007]数据备份 题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同 ...

  3. P3620 [APIO/CTSC 2007]数据备份[优先队列+贪心]

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

  4. 洛谷P3620 [APIO/CTSC 2007] 数据备份 [堆,贪心,差分]

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

  5. 洛谷P3620 [APIO/CTSC 2007] 数据备份

    题目 贪心+堆. 一般贪心题用到堆的时候都会存在一种反悔操作,因此这个题也不例外. 首先电缆一定是连接两个相邻的点的,这很好证明,其次一个点只能被一条电缆连接,所以我们通过选这个电缆,不选相邻电缆和选 ...

  6. 洛谷$P3620\ [APIO/CTSC 2007]$数据备份 贪心

    正解:贪心 解题报告: 传送门$QwQ$ $umm$感觉这种问题还蛮经典的,,,就选了某个就不能选另一个这样儿,就可以用堆模拟反悔操作 举个$eg$,如果提出了$a_i$,那就$a_{i-1}$和$a ...

  7. luogu P3620 [APIO/CTSC 2007]数据备份

    luogu 首先如果一条线不是了连接的相邻两个位置一定不优,把它拆成若干连接相邻位置的线.所以现在问题是有\(n\)个物品,选\(k\)个,要求选的位置不能相邻,求最小总和 如果没有选的位置不能相邻这 ...

  8. [APIO/CTSC 2007]数据备份(贪心+堆)

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

  9. 题解 P3620 【[APIO/CTSC 2007]数据备份】

    直接贪心(每次选最小)的话显然不对...样例都过不了... 选两个办公楼的时候,显然不能跨越另一个楼,这样不优... 于是 先把原数列处理成n-1个的数(每一个办公楼和上一个的距离),存在a[]中 题 ...

随机推荐

  1. shell练习--PAT题目1008:数组元素循环右移问题 (失败案例,运行超时)

    一个数组A中存有N(>)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥)个位置,即将A中的数据由(A​0​​A​1​​⋯A​N−1​​)变换为(A​N−M​​⋯A​N−1​​A ...

  2. 上采样 及 Sub-pixel Convolution (子像素卷积)

    参考:https://blog.csdn.net/leviopku/article/details/84975282 参考:https://blog.csdn.net/g11d111/article/ ...

  3. ASP.NET如何实现断点续传的上传、下载功能?

    1 背景 用户本地有一份txt或者csv文件,无论是从业务数据库导出.还是其他途径获取,当需要使用蚂蚁的大数据分析工具进行数据加工.挖掘和共创应用的时候,首先要将本地文件上传至ODPS,普通的小文件通 ...

  4. BZOJ1491 Red is good

    题目链接:Click here Solution: 考虑设\(f(i,j)\)表示当前还有\(i\)张红牌,\(j\)张黑牌时的期望收益 易得状态转移方程:\(f(i,j)=\frac{i}{i+j} ...

  5. JMS学习十一(ActiveMQ Consumer高级特性之独有消费者(Exclusive Consumer))

    一.简介 Queue中的消息是按照顺序被分发到consumers的.然而,当你有多个consumers同时从相同的queue中提取消息时, 你将失去这个保证.因为这些消息是被多个线程并发的处理.有的时 ...

  6. es之零停机重新索引数据

    实际生产,对于文档的操作,偶尔会遇到这种问题: 某一个字段的类型不符合后期的业务了,但是当前的索引已经创建了,我们知道es在字段的mapping建立后就不可再次修改mapping的值 比如: 1): ...

  7. [CSP-S模拟测试]:bird(线段树优化DP)

    题目传送门(内部题89) 输入格式 第一行两个数$n$和$k$,分别表示小鸟的只数和$R$装弹时间.接下来$n$行,每行两个数$l,r$表示$n$只小鸟初始时的头和尾的$x$坐标. 输出格式 输出一个 ...

  8. http中post 和 get 请求方法区别

    前言 做Web开发就一定会涉及到浏览器和服务器的交互,所以了解浏览器和服务器交互的方式就尤为重要.从接触B/S开始就已经接触到了get和post,但是对它们的了解确实不深入.在后来不断的做项目过程中, ...

  9. 分布式工作流任务调度系统Easy Scheduler正式开源

    分布式工作流任务调度系统Easy Scheduler正式开源 1.背景 在多位技术小伙伴的努力下,经过近2年的研发迭代.内部业务剥离及重构,也经历一批种子用户试用一段时间后,EasyScheduler ...

  10. leetcode-mid-sorting and searching-162. Find Peak Element

    mycode  54.81% class Solution(object): def findPeakElement(self, nums): """ :type num ...