Bzoj 2288 生日礼物题解
2288: 【POJ Challenge】生日礼物
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 856 Solved: 260
[Submit][Status][Discuss]
Description
ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1, A2, ..., AN. 她被允许选择不超过 M 个连续的部分作为自己的生日礼物。
自然地,ftiasch想要知道选择元素之和的最大值。你能帮助她吗?

Input
第1行,两个整数 N (1 ≤ N ≤ 105) 和 M (0 ≤ M ≤ 105), 序列的长度和可以选择的部分。
第2行, N 个整数 A1, A2, ..., AN (0 ≤ |Ai| ≤ 104), 序列。
Output
一个整数,最大的和。
Sample Input
2 -3 2 -1 2
Sample Output
HINT
Source
这道题当时第一眼以为连续的m个数,然后以为是二分加上单调队列,还好又读了一遍,发现是m个区间,这就比较有意思了。
首先,我们可以先把所有符号相同的区间合在一起,来简化一下问题,然后这道题就变成了在一个正数与负数相间的数列中找出m个数使他们的和最大,但是我们要注意一点,这些数其实还可以合并成一个数,所以我们不能拿贪心去做。所以我们可以把答案分为两种情况,第一,所有正数的个数小于等于m那么我们可以直接输出了,第二正数的个数大于m,那么我们就有又有两种选择了,舍去某个正数或通过一个负数将两个区间合并在一起。对于位于首尾两个位置的负数我们可以的知他们并无法连接两个正数,换言之,选他们并不能减少当前所选的区间,所以我们在一开始就应当把他们刨去。同时我们也可以发现如果我们选了一个负数那么两侧的正数是不能再被选择丢掉的,而整个序列又是正负相间的,所以我们就可以将这个问题转化为在当前数列中选取若干个不相邻的数数是他们的和最小。然后,这道题就是Bzoj1150数据备份了。
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cmath>
#include<map>
#include<vector>
#define N 100005
using namespace std;
int n,m,a[N],zz;
struct no
{
long long sum;
int mid;
bool friend operator > (no a,no b)
{
return a.sum>b.sum;
}
}node[N];
int pre[N],fro[N];
bool fw[N];
priority_queue<no,vector<no>,greater<no > > q1;
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
long long sm=,ans=,js=,la=;
for(int i=;i<=n;i++)
{
if(a[i]==)continue;
if(a[i]*la<)
{
zz++;
node[zz].sum=sm;
if(sm>)
{
js++;
ans+=sm;
}
sm=;
if(zz==&&la<)zz=;
}
la=a[i];
sm+=a[i];
}
if(sm>)
{
js++,ans+=sm;
zz++;
node[zz].sum=sm;
}
if(js<=m)
{
printf("%lld\n",ans);
exit();
}
m=js-m;
for(int i=;i<=zz;i++)
{
node[i].mid=i;
node[i].sum=abs(node[i].sum);
q1.push(node[i]);
pre[i]=i-,fro[i]=i+;
}
fro[zz]=;
node[].sum=0x7fffffff;
while(m--)
{
while(fw[q1.top().mid]) q1.pop();
no tt=q1.top();q1.pop();
int x=tt.mid;
ans-=tt.sum;
tt.sum=-tt.sum;
tt.sum+=node[pre[x]].sum+node[fro[x]].sum;
node[x].sum=tt.sum; fw[pre[x]]=fw[fro[x]]=;
pre[x]=pre[pre[x]];
fro[x]=fro[fro[x]];
pre[fro[x]]=x;
fro[pre[x]]=x;
q1.push(tt);
}
printf("%lld\n",ans);
return ;
}
Bzoj 2288 生日礼物题解的更多相关文章
- BZOJ 1179 Atm 题解
BZOJ 1179 Atm 题解 SPFA Algorithm Tarjan Algorithm Description Input 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来 ...
- BZOJ 2288 【POJ Challenge】生日礼物(贪心+优先队列)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2288 [题目大意] 给出一列数,求最多取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][ ...
- 【BZOJ 2288】 2288: 【POJ Challenge】生日礼物 (贪心+优先队列+双向链表)
2288: [POJ Challenge]生日礼物 Description ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1, A2, ..., AN. 她被允许选择不超 ...
- 【BZOJ 2288】 生日礼物
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2288 [算法] 先将这个序列的正负数合并起来,变成一个正负交替的序列 如果新序列的正 ...
- BZOJ 2288: 【POJ Challenge】生日礼物 堆&&链表
就是堆+链表,十分像 数据备份 对吧? 把相邻的正数和相邻的负数合并成一整个正数块和负数块,最后只剩一些交替相间的正块与负块了吧? 显然,正块的个数<=m时,全部选走就获得了最大权值,否则我们可 ...
- bzoj 2288: 【POJ Challenge】生日礼物【链表+堆】
参考:http://blog.csdn.net/w_yqts/article/details/76037315 把相同符号的连续数字加起来,合并后ans先贪心的加上所有正数,如果正数个数sum> ...
- BZOJ 2288: 【POJ Challenge】生日礼物 贪心 + 堆 + 链表
好像是模拟费用流 Code: #include <bits/stdc++.h> #define setIO(s) freopen(s".in","r" ...
随机推荐
- Win8 Metro(C#)数字图像处理--2.55OSTU法图像二值化
原文:Win8 Metro(C#)数字图像处理--2.55OSTU法图像二值化 [函数名称] Ostu法图像二值化 WriteableBitmap OstuThSegment(Writ ...
- Java底层知识学习:Bytecode and JMM
最近在跟着耗子哥的程序员练级指南学习Java底层知识,结合<深入理解Java虚拟机>这本书在看,写笔记,看资料,成长中…… 目前看完了第二章JMM和各内存区OOM的情况 一篇图文并茂介绍字 ...
- 零元学Expression Blend 4 - Chapter 12 用实例了解布局容器系列-「Viewbox」
原文:零元学Expression Blend 4 - Chapter 12 用实例了解布局容器系列-「Viewbox」 本系列将教大家以实做案例认识Blend 4 的布局容器,此章介绍的布局容器是Bl ...
- foreach获取索引值
List<" }; foreach (string item in items) { int index = items.IndexOf(item); Console.WriteLin ...
- C语言中.h和.c文件解析(转载)
转载:http://www.cnblogs.com/laojie4321/archive/2012/03/30/2425015.html 简单的说其实要理解C文件与头文件(即.h)有什么不同之处, ...
- Qt 开发WEB Services客户端代码(使用gSoap)
1. 首先下载gSoap开发包 http://sourceforge.net/projects/gsoap2 目录包含 wsdl2h.exe( 由wsdl生成接口头文件C/C++格式的头文件 ) ...
- 解除.NET中虚拟路径的疑惑
今天部署产品时,发现一个涉及到路径错误的bug,在开发环境下都OK,但是到了测试环境中却一直报错,经过一番排查,原来错误出在了HttpContext.Current.Server.MapPath这个方 ...
- 浅谈Java中的命名规范
现代软件架构的复杂性需要协同开发完成,如何高效地协同呢? 答案是:制定一整套统一的规范. 无规矩不成方圆,无规范难以协同,比如,制订交通法规表面上是要限制行车权,实际上是保障公众的人身安全,试想如果没 ...
- 10 table标签
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...
- MyBatis从入门到精通(三):MyBatis XML方式的基本用法之多表查询
最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 1. 多表查询 上篇博客中,我们示例的 ...