【BZOJ2288】生日礼物 [贪心]
生日礼物
Time Limit: 10 Sec Memory Limit: 128 MB
[Submit][Status][Discuss]
Description
ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1, A2, ..., AN. 她被允许选择不超过 M 个连续的部分作为自己的生日礼物。
自然地,ftiasch想要知道选择元素之和的最大值。你能帮助她吗?
Input
第1行,两个整数 N 和 M , 序列的长度和可以选择的部分。
第2行, N 个整数 A1, A2, ..., AN , 序列。
Output
一个整数,最大的和。
Sample Input
2 -3 2 -1 2
Sample Output
HINT
1 ≤ N ≤ 105, 0 ≤ M ≤ 105, 0 ≤ |Ai| ≤ 104
Solution
首先,我们可以把权值正负相同的连续的一段合并起来。Ans+=(所有正数),块数++。
然后把每一段的绝对值加入到小根堆里面。每次贪心取出最小的来,块数减去 1 直到满足题目要求为止。
为什么这样可以对呢?我们来讨论一下:
1. 如果删去的段是正数, 那么相当于不取这个。
2. 如果删去的段是负数,那么相当于取了这个段合并它左右的两个段。
但是!这样会有一个问题!就是无法考虑连续取5个段及以上的情况,并且无法保证:取了一个数不取相连的两个数(会导致块数不减)。
所以判断一下,每次取段的时候,删去左右两个小段,加上一个大段(他们三个合并的值)即可。
Code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<queue>
using namespace std;
typedef long long s64; const int ONE = ;
const int INF = ; int n, m;
int a[ONE], A[ONE];
int pre[ONE], suc[ONE];
int Ans, block; struct power
{
int id, val;
bool operator <(power a) const
{
return a.val < val;
}
};
priority_queue <power> q; int get()
{
int res=,Q=;char c;
while( (c=getchar())< || c> )
if(c=='-')Q=-;
res=c-;
while( (c=getchar())>= && c<= )
res=res*+c-;
return res*Q;
} int main()
{
n = get(); m = get();
for(int i = ; i <= n; i++) a[i] = get();
int from = ; while(a[from] <= ) from++;
int to = n; while(a[to] <= ) to--; n = ;
for(;from <= to;)
{
if( (a[from-] <= && a[from] <= ) || (a[from-] > && a[from] > ))
A[n] += a[from];
else A[++n] = a[from];
from++;
} for(int i = ; i <= n; i++)
{
pre[i] = i - ;
suc[i] = i + ;
if(A[i] > ) Ans += A[i], block++;
A[i] = abs(A[i]);
q.push( (power){i, A[i]} );
} if(block <= m) {printf("%d", Ans); return ;} pre[] = suc[n] = ; for(;;)
{
for(;;)
{
power u = q.top();
if(u.val != A[u.id]) q.pop();
else break;
} power u = q.top(); q.pop();
Ans -= u.val; if(pre[u.id] == ) A[suc[u.id]] = INF, pre[suc[u.id]] = ;
else
if(suc[u.id] == ) A[pre[u.id]] = INF, suc[pre[u.id]] = ;
else
{
A[u.id] = A[pre[u.id]] + A[suc[u.id]] - A[u.id];
A[pre[u.id]] = A[suc[u.id]] = INF;
pre[u.id] = pre[pre[u.id]];
suc[u.id] = suc[suc[u.id]];
pre[suc[u.id]] = suc[pre[u.id]] = u.id;
q.push( (power){u.id, A[u.id]} );
} block--; if(block <= m) break;
} printf("%d", Ans);
}
【BZOJ2288】生日礼物 [贪心]的更多相关文章
- 2018.09.30 bzoj2288:生日礼物(贪心+线段树)
传送门 线段树经典题目. 每次先找到最大子段和来更新答案,然后利用网络流反悔退流的思想把这个最大字段乘-1之后放回去. 代码: #include<bits/stdc++.h> #defin ...
- bzoj2288 生日礼物 (线段树)
我当然想选最大的子段和啦 但要选M次 那不一定就是最好的 所以提供一个反悔的选项,我选了一段以后,就把它们乘个-1,然后再选最好的(类似于网络流的思路) 这个可以用线段树来维护,记一个区间包含左端点/ ...
- BZOJ2288 生日礼物
本题是数据备份的进阶版. 首先去掉所有0,把连续的正数/负数连起来. 计算所有正数段的个数与总和. 然后考虑数据备份,有一点区别: 如果我们在数列中选出一个负数,相当于把它左右连起来. 选出一个正数, ...
- P2564 [SCOI2009]生日礼物 贪心
https://www.luogu.org/problemnew/show/P2564) 题意 有n个珠子,包括k中颜色,找出长度最小的一个区间,使得这个区间中包含所有的颜色. 思路 把n个珠子按照位 ...
- BZOJ 2288: 【POJ Challenge】生日礼物 贪心 + 堆 + 链表
好像是模拟费用流 Code: #include <bits/stdc++.h> #define setIO(s) freopen(s".in","r" ...
- 我的刷题单(8/37)(dalao珂来享受切题的快感
P2324 [SCOI2005]骑士精神 CF724B Batch Sort CF460C Present CF482A Diverse Permutation CF425A Sereja and S ...
- [bzoj2288][pojChallenge]生日礼物【贪心+堆+链表】
题目描述 ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1, A2, -, AN. 她被允许选择不超过 M 个连续的部分作为自己的生日礼物. 自然地,ftiasch想要知 ...
- [bzoj2288]【POJ Challenge】生日礼物_贪心_堆
[POJ Challenge]生日礼物 题目大意:给定一个长度为$n$的序列,允许选择不超过$m$个连续的部分,求元素之和的最大值. 数据范围:$1\le n, m\le 10^5$. 题解: 显然的 ...
- [BZOJ2288&BZOJ1150]一类堆+链表+贪心问题
今天我们来介绍一系列比较经典的堆+链表问题.这类问题的特点是用堆选取最优解,并且通过一些加减操作来实现"反悔". 在看题之前,我们先来介绍一个神器:手写堆. 手写堆的一大好处就是可 ...
随机推荐
- iOS-tableView刷新指定行,组
/一个section刷新 NSIndexSet *indexSet=[[NSIndexSet alloc]initWithIndex:]; [tableview reloadSections:inde ...
- javaweb引用jar类库的问题
JAVAWEB中,需要引用的jar类库必须放在/WebContent/WEB-INF/lib文件夹中.不然就会各种报错.
- activity属性设置大全
activity属性设置大全 android:allowTaskReparenting=["true" | "false"] 是否允许activ ...
- C/S结构 B/S结构
[1]C/S 结构,即大家熟知的客户机和服务器结构.它是软件系统体系结构,通过它可以充分利用两端硬件环境的优势,将任务合理分配到Client端和Server端来实现,降低了系统的通讯开销.目前大多数应 ...
- Jekyll 使用 Rouge 主题
今日发现我的 Github Pages 中的代码并没有高亮,看了一下代码发现,原来的没有设置 css 样式的原因,我使用的代码高亮器是 rouge highlighter: rouge Rouge 是 ...
- centos7 nginx端口转发出现502的其中一种原因
在排查了一系列可能的原因后仍无法解决,经资料查阅可能是SELinux造成,SELinux很强大但若配置不当也会造成很多组件无法正常使用,这里直接将其关闭: //打开配置文件 vi /etc/selin ...
- android eclipse 添加libs文件夹
导入一个项目发现没有libs文件夹,后来z自己新建了个lib文件夹,但是总是不行,后来发现错了,应该是libs文件夹.建完了之后,系统会自动在build path中把这个文件夹添加进来的:个人无须操作
- MEX程序中的mexFunction函数【转】
与C中的main函数一样,MEX程序中的开始函数为mexFunction.默认变量参数是: void mexFunction(int nlhs, mxArray *plhs[], int nrhs, ...
- BZOJ2458:[BJOI2011]最小三角形——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=2458 Description Xaviera现在遇到了一个有趣的问题. 平面上有N个点,Xavier ...
- 【枚举暴力】【UVA11464】 Even Parity
传送门 Description 给你一个0/1矩阵,可以将矩阵中的0变成1,问最少经过多少此操作使得矩阵任意一元素四周的元素和为偶数. Input 第一行是一个整数T代表数据组数,每组数据包含以下内容 ...