BZOJ2288:[POJ Challenge]生日礼物——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=2288
ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1, A2, ..., AN. 她被允许选择不超过 M 个连续的部分作为自己的生日礼物。
自然地,ftiasch想要知道选择元素之和的最大值。你能帮助她吗?
这题很像BZOJ1150:[APIO/CTSC2007]数据备份,但如果没有做过的话其实也不要紧。
参考:https://www.cnblogs.com/zyfzyf/p/4114774.html感觉hzwer博客不是很好懂。
我们首先将相同符号的点缩起来,去掉首末的负结点,然后思考。
如果当前的正数个数<=m显然就求一遍和即可。
如果>m的话就有两种选择了:
1.忍痛割爱弃掉一个正数。
2.选择一个负数,将两旁正数连同负数一起缩进来。
我们发现这两个操作都是在原ans的基础上支付我们选择的点代价的,因此我们支付的代价越少越好,故我们将点权的abs放入小根堆里,每次拿出来之后和两边的点缩起来即可。
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
#define fi first
#define se second
const int N=1e5+;
const int INF=1e9+;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct node{
int x,y;
node(int xx=,int yy=){
x=xx;y=yy;
}
bool operator <(const node &b)const{
return abs(x)>abs(b.x);
}
};
priority_queue<node>q;
int n,m,cnt,tmp,a[N],b[N],pre[N],nxt[N];
int main(){
n=read(),m=read();
for(int i=;i<=n;i++){
a[++tmp]=read();
if(!a[tmp])tmp--;
} b[++cnt]=a[];
for(int i=;i<=tmp;i++){
if((a[i]>&&a[i-]>)||(a[i]<&&a[i-]<))b[cnt]+=a[i];
else{
if(cnt==&&b[cnt]<)cnt--;
b[++cnt]=a[i];
}
}
if(b[cnt]<)cnt--; int ans=,tot=;
for(int i=;i<=cnt;i++){
if(b[i]>)ans+=b[i],tot++;
q.push(node(b[i],i));
} for(int i=;i<=cnt+;i++)pre[i]=i-,nxt[i]=i+;
pre[]=;nxt[cnt+]=cnt+;
b[]=b[cnt+]=-INF; while(tot>m){
node p=q.top();q.pop();
if(b[p.y]!=p.x)continue;
ans-=abs(p.x);
b[p.y]=b[pre[p.y]]+b[nxt[p.y]]+p.x;
b[pre[p.y]]=b[nxt[p.y]]=-INF;
q.push(node(b[p.y],p.y));
pre[p.y]=pre[pre[p.y]];nxt[pre[p.y]]=p.y;
nxt[p.y]=nxt[nxt[p.y]];pre[nxt[p.y]]=p.y;
tot--;
}
printf("%d\n",ans);
return ;
}
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/ +
+++++++++++++++++++++++++++++++++++++++++++
BZOJ2288:[POJ Challenge]生日礼物——题解的更多相关文章
- [bzoj2288][POJ Challenge]生日礼物
用堆维护双向链表来贪心... 数据范围显然不容许O(nm)的傻逼dp>_<..而且dp光是状态就n*m个了..显然没法优化 大概就会想到贪心乱搞了吧...一开始想贪心地通过几段小的负数把正 ...
- BZOJ3502PA2012Tanie linie&BZOJ2288[POJ Challenge]生日礼物——模拟费用流+链表+堆
题目描述 n个数字,求不相交的总和最大的最多k个连续子序列. 1<= k<= N<= 1000000. 输入 输出 样例输入 5 2 7 -3 4 -9 5 样例输出 13 根据 ...
- BZOJ2288:[POJ Challenge]生日礼物
浅谈堆:https://www.cnblogs.com/AKMer/p/10284629.html 题目传送门:https://lydsy.com/JudgeOnline/problem.php?id ...
- bzoj2288【POJ Challenge】生日礼物*
bzoj2288[POJ Challenge]生日礼物 题意: 给一个序列,求不超过m个连续的部分,使元素和最大.序列大小≤100000 题解: 先把连续的正数和负数合并起来,接着如果正数个数小于m则 ...
- BZOJ2288: 【POJ Challenge】生日礼物
2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 284 Solved: 82[Submit][St ...
- [bzoj2288]【POJ Challenge】生日礼物_贪心_堆
[POJ Challenge]生日礼物 题目大意:给定一个长度为$n$的序列,允许选择不超过$m$个连续的部分,求元素之和的最大值. 数据范围:$1\le n, m\le 10^5$. 题解: 显然的 ...
- 2288.【POJ Challenge】生日礼物 链表+堆+贪心
BZOJ2288 [POJ Challenge]生日礼物 题意: 给一个长度为\(n\)的数组,最多可以选\(m\)个连续段,问选取的最大值是多少 题解: 先把连续的符号相同的值合并,头和尾的负数去掉 ...
- 【链表】BZOJ 2288: 【POJ Challenge】生日礼物
2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 382 Solved: 111[Submit][S ...
- bzoj 2288 【POJ Challenge】生日礼物 双向链表+堆优化
2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1003 Solved: 317[Submit][ ...
随机推荐
- [学习笔记]PCL使用心得
最近开始做研究生毕设,有一部分因为没有什么好的思路,就把以前用过的PCL点云搬出来,重新用源码装了一遍PCL,一开始装的过程中没什么大问题,在后面用的时候碰到了很多小问题,特此记录. 1.PCL版本问 ...
- DMA-Direct Memory Access
什么是? DMA 首先它是一种数据的传输方式:其次传输包括从设备到内存.内存到存储.内存到内存等:最后,它是在不经过cpu的情况下实现数据传输.. DAM主要有共享缓存DMA,Scatter/Gath ...
- Tomcat源码学习(3)—— Digester介绍
Digester方法详解: 通读Digester之前先分析下他的结构: 1.1该类继承了方法DefaultHandler2,DefaultHandler2继承了DefaultHandler是和sax解 ...
- django orm 操作表
django orm 操作表 1.基本操作 增 models.Tb1.objects.create(c1='xx', c2='oo') 增加一条数据,可以接受字典类型数据 **kwargs inser ...
- NO.2:自学tensorflow之路------BP神经网络编程
引言 在上一篇博客中,介绍了各种Python的第三方库的安装,本周将要使用Tensorflow完成第一个神经网络,BP神经网络的编写.由于之前已经介绍过了BP神经网络的内部结构,本文将直接介绍Tens ...
- Tree - Information Theory
This will be a series of post about Tree model and relevant ensemble method, including but not limit ...
- mkfs命令详解
mkfs命令-->make filesystem的缩写:用来在特定的分区建立Linux文件系统 [命令作用] 该命令用来在特定的分区创建linux文件系统,常见的文件系统有ext2,ex ...
- Python基础_可迭代的/迭代器/生成器
介绍 可迭代的:内部实现了__iter__方法 迭代器:内部实现了__iter__,__next__方法 生成器:yield,yield from 使用 __iter__() __next__() _ ...
- java工程文件路径的问题
String classpath = this.getClass().getResource("/").getPath().replaceFirst("/WEB-INF/ ...
- 第三周linux学习
实验二 Linux下C语言编程基础 一.实验目的 1. 熟悉Linux系统下的开发环境 2. 熟悉vi的基本操作 3. 熟悉gcc编译器的基本原理 4. 熟练使用gcc编译器的常用选项 5 .熟练使用 ...