题目描述

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代码

  1. #include <bits/stdc++.h>
  2. #define ll long long
  3. #define ms(a, b) memset(a, b, sizeof(a))
  4. #define inf 0x3f3f3f3f
  5. #define N 100005
  6. using namespace std;
  7. template <typename T>
  8. inline void read(T &x) {
  9. x = 0; T fl = 1;
  10. char ch = 0;
  11. while (ch < '0' || ch > '9') {
  12. if (ch == '-') fl = -1;
  13. ch = getchar();
  14. }
  15. while (ch >= '0' && ch <= '9') {
  16. x = (x << 1) + (x << 3) + (ch ^ 48);
  17. ch = getchar();
  18. }
  19. x *= fl;
  20. }
  21. struct node {
  22. int id, val;
  23. node(int id, int val): id(id), val(val){}
  24. bool operator <(const node &rhs) const {
  25. return abs(val) > abs(rhs.val);
  26. }
  27. };
  28. int a[N], b[N], lst[N], nxt[N];
  29. priority_queue<node> q;
  30. int tot, n, m, ans;
  31. bool vis[N];
  32. void remove(int x) {
  33. vis[x] = 1;
  34. lst[nxt[x]] = lst[x];
  35. nxt[lst[x]] = nxt[x];
  36. }
  37. int main() {
  38. memset(vis, 0, sizeof(vis));
  39. read(n); read(m);
  40. for (int i = 1; i <= n; i ++) read(b[i]);
  41. tot = 1;
  42. for (int i = 1; i <= n; i ++) {
  43. if ((ll)a[tot] * b[i] >= 0) a[tot] += b[i];
  44. else a[++ tot] = b[i];
  45. }
  46. n = tot;
  47. tot = 0;
  48. for (int i = 1; i <= n; i ++) {
  49. if (a[i] > 0) tot ++, ans += 1ll * a[i];
  50. }
  51. for (int i = 1; i <= n; i ++) {
  52. nxt[i] = i + 1;
  53. lst[i] = i - 1;
  54. q.push(node(i, a[i]));
  55. }
  56. while (tot > m) {
  57. tot --;
  58. while (vis[q.top().id]) q.pop();
  59. int x = q.top().id;
  60. q.pop();
  61. if (lst[x] != 0 && nxt[x] != n + 1) ans -= abs(a[x]);
  62. else if (a[x] > 0) ans -= a[x];
  63. else {
  64. tot ++;
  65. continue;
  66. }
  67. a[x] = a[lst[x]] + a[nxt[x]] + a[x];
  68. remove(nxt[x]);
  69. remove(lst[x]);
  70. q.push(node(x, a[x]));
  71. }
  72. printf("%d\n", ans);
  73. return 0;
  74. }

[bzoj2288][pojChallenge]生日礼物【贪心+堆+链表】的更多相关文章

  1. BZOJ 2288: 【POJ Challenge】生日礼物 贪心 + 堆 + 链表

    好像是模拟费用流 Code: #include <bits/stdc++.h> #define setIO(s) freopen(s".in","r" ...

  2. BZOJ_2151_种树_贪心+堆+链表

    BZOJ_2151_种树_贪心+堆 Description A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树.园林部门得到指令后,初步规划出n个种树的位置,顺时针编 ...

  3. BZOJ2288 【POJ Challenge】生日礼物 【堆 + 链表】

    题目 ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1, A2, ..., AN. 她被允许选择不超过 M 个连续的部分作为自己的生日礼物. 自然地,ftiasch想要知 ...

  4. 【BZOJ2288】生日礼物 [贪心]

    生日礼物 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description ftiasch 18岁生日的时候, ...

  5. [luogu3620][APIO/CTSC 2007]数据备份【贪心+堆+链表】

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

  6. BZOJ2151 种树(贪心+堆+链表/wqs二分+动态规划)

    dp容易想到,但没法进一步优化了. 考虑贪心,每次选出价值最大的物品.但这显然是不对的因为会影响其他物品的选择. 于是考虑加上反悔操作.每次选出一个物品后,将其相邻两物品删除,再将原物品价值变为相邻两 ...

  7. [BZOJ2288&BZOJ1150]一类堆+链表+贪心问题

    今天我们来介绍一系列比较经典的堆+链表问题.这类问题的特点是用堆选取最优解,并且通过一些加减操作来实现"反悔". 在看题之前,我们先来介绍一个神器:手写堆. 手写堆的一大好处就是可 ...

  8. BZOJ 2288: 【POJ Challenge】生日礼物 堆&&链表

    就是堆+链表,十分像 数据备份 对吧? 把相邻的正数和相邻的负数合并成一整个正数块和负数块,最后只剩一些交替相间的正块与负块了吧? 显然,正块的个数<=m时,全部选走就获得了最大权值,否则我们可 ...

  9. 【贪心+堆】XMU 1584 小明的烦恼

    题目链接: http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1584 题目大意: 给n(n<=100 000)个任务的耗时和截至时间,问最少不能 ...

随机推荐

  1. MySQL中关于数据类型指定宽度之后的情况

    概述 MySQL有很多种数据类型,最常用的就是int,char,varchar,这些类型在创建表的时候都可以指定该字段的宽度,方法是在类型后面加一个括号,括号中写宽度就可以了. 但是,在指定宽度之后, ...

  2. 爬虫——selenium基础

    Selenium,自动化浏览器技术.主要用于web应用自动测试和自动完成web基本任务管理.官方网站:https://selenium-python.readthedocs.io/getting-st ...

  3. Rime 小狼毫 注意事项

    https://rime.im/https://github.com/rime/weasel/pulse 打不出中文可能是,没有五笔需要的文件: wubi_pinyin.schema.yamlCtrl ...

  4. 临时的ThisCall

    // 获取当前定位 changeCity: function () { let that = this; that.locationClose(); Upj._changeCity().then((d ...

  5. bootstrap3兼容IE8

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. vue 项目使用 webpack 构建自动获取电脑ip地址

    1.开发 H5 时移动端,经常会使用真机进行调试本地环境.webpack 配置服务器好多脚手架写的都是固定的,而在团队开发中需要每人配置自己的本机 ip 进行开发,每次开启开发环境的都需要修改,并且还 ...

  7. PhpStorm 配置链接远程虚拟机

    安装好了 PhpStorm 之后,打开项目文件夹,接着点击工具栏 Tools: 2.接着点击 tools>Deployment: 3.点击Configuration 开始配置    4.填好箭头 ...

  8. Decoder is not a @Sharable handler, so can't be added or removed multiple times

    Decoder is not a @Sharable handler, so can't be added or removed multiple times final MyMessageDecod ...

  9. Golang的channel使用以及并发同步技巧

    在学习<The Go Programming Language>第八章并发单元的时候还是遭遇了不少问题,和值得总结思考和记录的地方. 做一个类似于unix du命令的工具.但是阉割了一些功 ...

  10. DBX error:Driver could not be properly initialized .... 解决办法

    系统: win7 64位+ MySql 将libmysql.dll和Dbxmys.dll 拷到 C:\Windows\SysWOW64 目录. ( 64位系统)     32位则拷到  c:\wind ...