【题目链接】

https://www.lydsy.com/JudgeOnline/problem.php?id=2288

【算法】

先将这个序列的正负数合并起来,变成一个正负交替的序列

如果新序列的正数个数小于等于M,那么直接输出正数的和即可

否则,我们可以将某些正数和负数合并起来,或者不要某些正数

将所有数按绝对值排序,放入堆中,问题就转化为了 : 在这些数中选出(Cnt - M)个数(其中Cnt为正数的个数),

选了一个数后相邻的两个数就不能选,使得最后的和尽可能小

这个问题可以用CTSC2007数据备份的方法来解决,详见 : https://www.cnblogs.com/evenbao/p/9252503.html

【代码】

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + ;
const int INF = 2e9; struct info
{
int d,pos;
}; int i,n,m,l,r,cnt,ans,len;
int a[MAXN],b[MAXN],val[MAXN],pre[MAXN],nxt[MAXN];
bool visited[MAXN];
info tmp; class Heap
{
private :
int tot;
info hp[MAXN];
public :
inline bool cmp(info a,info b)
{
return a.d < b.d;
}
inline void Up(int x)
{
if (x == ) return;
int fa = x >> ;
if (cmp(hp[x],hp[fa]))
{
swap(hp[x],hp[fa]);
Up(fa);
}
}
inline void Down(int x)
{
int son = x << ;
if (son > tot) return;
if ((son + <= tot) && cmp(hp[son+],hp[son])) son++;
if (cmp(hp[son],hp[x]))
{
swap(hp[son],hp[x]);
Down(son);
}
}
inline void insert(info x)
{
tot++;
hp[tot] = x;
Up(tot);
}
inline void del()
{
swap(hp[],hp[tot]);
tot--;
Down();
}
inline info get()
{
return hp[];
}
} H; int main()
{ scanf("%d%d",&n,&m);
for (i = ; i <= n; i++) scanf("%d",&a[i]);
while (n && a[n] <= ) n--;
i = ;
while (i <= n && a[i] <= ) i++;
if (i > n)
{
printf("%d\n",);
return ;
}
for (; i <= n; i++)
{
if ((a[i] > && a[i-] > ) || (a[i] <= && a[i-] <= )) b[len] += a[i];
else b[++len] = a[i];
}
for (i = ; i <= len; i++)
{
if (b[i] > )
{
ans += b[i];
cnt++;
} else b[i] = -b[i];
}
if (cnt <= m)
{
printf("%d\n",ans);
return ;
}
for (i = ; i <= len; i++)
{
pre[i] = i - ;
nxt[i] = i + ;
H.insert((info){b[i],i});
}
b[] = b[len+] = INF;
for (i = m; i < cnt; i++)
{
tmp = H.get();
while (visited[tmp.pos])
{
H.del();
tmp = H.get();
}
ans -= tmp.d;
H.del();
visited[pre[tmp.pos]] = true;
visited[nxt[tmp.pos]] = true;
b[tmp.pos] = b[pre[tmp.pos]] + b[nxt[tmp.pos]] - tmp.d;
nxt[pre[pre[tmp.pos]]] = tmp.pos;
pre[tmp.pos] = pre[pre[tmp.pos]];
pre[nxt[nxt[tmp.pos]]] = tmp.pos;
nxt[tmp.pos] = nxt[nxt[tmp.pos]];
H.insert((info){b[tmp.pos],tmp.pos});
}
printf("%d\n",ans); return ; }

【BZOJ 2288】 生日礼物的更多相关文章

  1. Bzoj 2288 生日礼物题解

    2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 856  Solved: 260[Submit][S ...

  2. 【链表】BZOJ 2288: 【POJ Challenge】生日礼物

    2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 382  Solved: 111[Submit][S ...

  3. bzoj 2288 【POJ Challenge】生日礼物 双向链表+堆优化

    2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1003  Solved: 317[Submit][ ...

  4. 【BZOJ 2288】 2288: 【POJ Challenge】生日礼物 (贪心+优先队列+双向链表)

    2288: [POJ Challenge]生日礼物 Description ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1, A2, ..., AN. 她被允许选择不超 ...

  5. BZOJ 2288 【POJ Challenge】生日礼物(贪心+优先队列)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2288 [题目大意] 给出一列数,求最多取m段连续的数字,使得总和最大 [题解] 首先我 ...

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

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

  7. bzoj 2288: 【POJ Challenge】生日礼物【链表+堆】

    参考:http://blog.csdn.net/w_yqts/article/details/76037315 把相同符号的连续数字加起来,合并后ans先贪心的加上所有正数,如果正数个数sum> ...

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

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

  9. [BZOJ 1293] 生日礼物

    Link: BZOJ 1293 传送门 Solution: 这题直接上尺取法就行了吧 先将每种颜色第一个放入优先队列,用$mx$维护当前的末尾位置 每次取出第一个颜色,更新答案.将其下一个放入队列中去 ...

随机推荐

  1. SQL基本操作——case end

    case end进行多条件的判断 --查看Person表 select * from Person --对math字段进行条件判断 select name,数学成绩= case then '优' th ...

  2. git使用原理

    如果需要新建仓库: mkdir new_artcle//artcle为文件名 cd new_artcle//进入该目录 git init //初始化工作空间 git add 文件名(article) ...

  3. Python语言之数据结构2(字典,引用)

    1.字典 键值对. dict={ "key1" : "value1", "key2" : "value2" } #add ...

  4. Web 服务器与应用服务器的区别是什么?

    不太严谨的说法:web服务器就是负责接收用户的Request,然后响应html等给客户浏览器.应用服务器处理一些业务逻辑等. 作者:luo链接:https://www.zhihu.com/questi ...

  5. C# 金钱添加逗号0000

    private void Form1_Load(object sender, EventArgs e) { decimal dd = (decimal)11234567890.01; string d ...

  6. day12-闭包函数、装饰器

    目录 闭包函数 装饰器 无参装饰器 有参装饰器 装饰器模板 闭包函数 之前我们都是通过参数将外部的值传给函数,而闭包打破了层级关系,把局部变量拿到全局使用,并把外部的变量封装到内部函数中,然后下次直接 ...

  7. GFS分布式文件系统脚本

    #!/bin/bashfor i in $(fdisk -l | grep -wo "/dev/sd[b-z]" | sort)dodd if=/dev/zero of=$i bs ...

  8. Centos7搭建ansible运维自动化工具

    1)设置主机名和hosts文件 2)配置阿里云repo源 Wget -O /etc/yum.repos.d/aliyun.repo https://mirrors.aliyun.com/repo/Ce ...

  9. jQuery练习:表单模态框

    代码:基于事件冒泡原理和事件委托 <!DOCTYPE html> <html lang="zh-cn"> <head> <meta cha ...

  10. 读取json文件并把uft-8转换为ascii

    #!/usr/bin/python import sys import json as js import codecs import collections #reload(sys) #sys.se ...