[bzoj2288][pojChallenge]生日礼物【贪心+堆+链表】
题目描述
ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1, A2, …, AN. 她被允许选择不超过 M 个连续的部分作为自己的生日礼物。
自然地,ftiasch想要知道选择元素之和的最大值。你能帮助她吗?
分析
这道题目还是非常简单的,和数据备份几乎是一样的,吐槽完毕。
参照之前我们的思路,因为是m段不同的部分,那么很明显,一段全是同一符号的一定是一起被一起选走,那么我们首先将原序列变换成只有正负交叉的序列,这样保证了我们能够一次就拿掉整个区间。
因为我们需要让和最大,那么有两种情况:
- 正数区间
- 正数区间+负数区间+...
那么我们思考一个贪心,如果一个正数区间非常的大,那么我们一定会选择这个区间,反之如果一个区间非常的小,也就是负数非常的大,那么我们就一定不会选择这个区间。从中显然推出我们需要按照绝对值排序,排序过程用优先队列来实现。
如果一开始正数区间个数就小于了m个,那么就可以直接不用遍历,反之我们需要去掉一些区间:
那么如果选正数,就意味着不选这个数,也就是直接删掉,因为后面还有更优的答案,tot-1。
如果选的是负数,说明左右区间合并,因为我们是绝对值较小,那么对于我们答案的影响一定是最小的,那么tot-1,合并区间。
否则那么就tot+1。
合并区间的操作和数据备份是一样的:https://www.cnblogs.com/chhokmah/p/10557925.html。
ac代码
#include <bits/stdc++.h>
#define ll long long
#define ms(a, b) memset(a, b, sizeof(a))
#define inf 0x3f3f3f3f
#define N 100005
using namespace std;
template <typename T>
inline void read(T &x) {
x = 0; T fl = 1;
char ch = 0;
while (ch < '0' || ch > '9') {
if (ch == '-') fl = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
x *= fl;
}
struct node {
int id, val;
node(int id, int val): id(id), val(val){}
bool operator <(const node &rhs) const {
return abs(val) > abs(rhs.val);
}
};
int a[N], b[N], lst[N], nxt[N];
priority_queue<node> q;
int tot, n, m, ans;
bool vis[N];
void remove(int x) {
vis[x] = 1;
lst[nxt[x]] = lst[x];
nxt[lst[x]] = nxt[x];
}
int main() {
memset(vis, 0, sizeof(vis));
read(n); read(m);
for (int i = 1; i <= n; i ++) read(b[i]);
tot = 1;
for (int i = 1; i <= n; i ++) {
if ((ll)a[tot] * b[i] >= 0) a[tot] += b[i];
else a[++ tot] = b[i];
}
n = tot;
tot = 0;
for (int i = 1; i <= n; i ++) {
if (a[i] > 0) tot ++, ans += 1ll * a[i];
}
for (int i = 1; i <= n; i ++) {
nxt[i] = i + 1;
lst[i] = i - 1;
q.push(node(i, a[i]));
}
while (tot > m) {
tot --;
while (vis[q.top().id]) q.pop();
int x = q.top().id;
q.pop();
if (lst[x] != 0 && nxt[x] != n + 1) ans -= abs(a[x]);
else if (a[x] > 0) ans -= a[x];
else {
tot ++;
continue;
}
a[x] = a[lst[x]] + a[nxt[x]] + a[x];
remove(nxt[x]);
remove(lst[x]);
q.push(node(x, a[x]));
}
printf("%d\n", ans);
return 0;
}
[bzoj2288][pojChallenge]生日礼物【贪心+堆+链表】的更多相关文章
- BZOJ 2288: 【POJ Challenge】生日礼物 贪心 + 堆 + 链表
好像是模拟费用流 Code: #include <bits/stdc++.h> #define setIO(s) freopen(s".in","r" ...
- BZOJ_2151_种树_贪心+堆+链表
BZOJ_2151_种树_贪心+堆 Description A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树.园林部门得到指令后,初步规划出n个种树的位置,顺时针编 ...
- BZOJ2288 【POJ Challenge】生日礼物 【堆 + 链表】
题目 ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1, A2, ..., AN. 她被允许选择不超过 M 个连续的部分作为自己的生日礼物. 自然地,ftiasch想要知 ...
- 【BZOJ2288】生日礼物 [贪心]
生日礼物 Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description ftiasch 18岁生日的时候, ...
- [luogu3620][APIO/CTSC 2007]数据备份【贪心+堆+链表】
题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家中尽享计算机游戏 ...
- BZOJ2151 种树(贪心+堆+链表/wqs二分+动态规划)
dp容易想到,但没法进一步优化了. 考虑贪心,每次选出价值最大的物品.但这显然是不对的因为会影响其他物品的选择. 于是考虑加上反悔操作.每次选出一个物品后,将其相邻两物品删除,再将原物品价值变为相邻两 ...
- [BZOJ2288&BZOJ1150]一类堆+链表+贪心问题
今天我们来介绍一系列比较经典的堆+链表问题.这类问题的特点是用堆选取最优解,并且通过一些加减操作来实现"反悔". 在看题之前,我们先来介绍一个神器:手写堆. 手写堆的一大好处就是可 ...
- BZOJ 2288: 【POJ Challenge】生日礼物 堆&&链表
就是堆+链表,十分像 数据备份 对吧? 把相邻的正数和相邻的负数合并成一整个正数块和负数块,最后只剩一些交替相间的正块与负块了吧? 显然,正块的个数<=m时,全部选走就获得了最大权值,否则我们可 ...
- 【贪心+堆】XMU 1584 小明的烦恼
题目链接: http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1584 题目大意: 给n(n<=100 000)个任务的耗时和截至时间,问最少不能 ...
随机推荐
- Django之在Python中调用Django环境
Django之在Python中调用Django环境 新建一个py文件,在其中写下如下代码: import os if __name__ == '__main__': os.environ.setdef ...
- 聊一聊跨域,Vue向Django请求数据的一些问题
1.做前后端分离 前端使用Vue程序,后端使用Django配合rest-framework. 那么前端Vue通过API接口拿到数据会出现跨域的问题,JSONP只是在get中会用到的,所以这里使用cor ...
- 【转】Word之表格、图片的题注(抬头)自动编号
问:word中的表格怎么自动插入题注(即表头的编号自动编号)? 答: 1首先搞清楚自动编号的意思.自动插入题注的意思是,在你在word中新建或者复制一个word表格的时候,表头的编号就自动生成了,而不 ...
- 01-学习vue前的准备工作
起步 1.扎实的HTML/CSS/Javascript基本功,这是前置条件. 2.不要用任何的构建项目工具,只用最简单的<script>,把教程里的例子模仿一遍,理解用法.不推荐上来就直接 ...
- React Native之TextInput的介绍与使用(富文本封装与使用实例,常用输入框封装与使用实例)
React Native之TextInput的介绍与使用(富文本封装与使用实例,常用输入框封装与使用实例) TextInput组件介绍 TextInput是一个允许用户在应用中通过键盘输入文本的基本组 ...
- Laravel 5.2+ 使用url()全局函数返回前一个页面的地址
注意:文章标题中5.2+表示该文章内容可向上兼容,适用于Laravel版本5.2及更高(目前最新为5.6),但不可向下兼容,即不适用于5.2版本以下.推荐大家花一点点时间,将自己的Laravel更新至 ...
- vue.js 添加 fastclick的支持
fastclick:处理移动端click事件300毫秒延迟 1.兼容性 iOS 3及更高版本的移动Safari iOS 5及更高版本的Chrome Android上的Chrome(ICS) Opera ...
- Java语言中姐种遍历List的方法总结
遍历 List 的方法: 1. for 2. advanced for 3. Iterator 4. while 5. ListIterator List<E> list 1. for f ...
- 在linux命令下访问url
1.elinks - lynx-like替代角色模式WWW的浏览器 例如: elinks --dump http://www.baidu.com 2.wget 这个会将访问的首页下载到本地 [root ...
- DAY04、流程控制if、while、for
一.if 判断 语法一: if 条件: # 以下是上一条if 的子代码块 print(子代码1) print(子代码2) print(子代码3) 示例: # 路边飘过一个生物,要不要表白? sex = ...