BZOJ3502PA2012Tanie linie&BZOJ2288[POJ Challenge]生日礼物——模拟费用流+链表+堆

时间:2022-09-06 08:34:06

题目描述

n个数字,求不相交的总和最大的最多k个连续子序列。
 1<= k<= N<= 1000000。

输入

输出

样例输入

5 2
7 -3 4 -9 5

样例输出

13
 
根据贪心的思想可以知道对于一段连续的正数或负数一定是一起选或者一起不选,那么我们可以将原序列连续的正数或负数缩成一个数,并将中间的$0$及两端的负数去掉,这样序列就变成了正负正负……负正的形式。先贪心地将所有正数选取,如果正数个数$\le k$直接输出正数和就是最优方案,否则我们需要去掉一些正数或选取一些两个正数之间的负数。可以发现无论是去掉正数还是选取负数,答案减少的量都是这个数的绝对值。而根据贪心的原则,如果去掉一个正数一定不会再选取相邻的两个负数,同样选取一个负数一定不会去掉相邻的两个正数。假设序列有$m$个正数,那么问题就变成了给出一个序列(每个数权值为之前的正负序列对应数的绝对值),选出$m-k$个数且不能选取相邻的数使选取数的总和最小,做法和BZOJ1150相同:维护所有数的小根堆,每次取出堆顶$b$计入答案并将与堆顶相邻的两个数$a,c$删除,将权值为$a+c-b$的一个新数插入到原来堆顶的位置。最后用双向链表维护相邻关系。
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define pr pair<ll,int>
using namespace std;
ll s[1000010];
int pre[1000010];
int suf[1000010];
int vis[1000010];
int tot;
int n,k;
ll ans,x;
priority_queue< pr,vector<pr>,greater<pr> >q;
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%lld",&x);
if(x>0)
{
ans+=x;
if(s[tot]>0)
{
s[tot]+=x;
}
else
{
s[++tot]=x;
}
}
if(x<0)
{
if(s[tot]<=0)
{
s[tot]+=x;
}
else
{
s[++tot]=x;
}
}
}
if(s[tot]<=0)
{
tot--;
}
n=tot;
if((n+1)/2<=k)
{
printf("%lld",ans);
return 0;
}
k=(n+1)/2-k;
for(int i=1;i<=n;i++)
{
pre[i]=i-1;
suf[i]=i+1;
s[i]=abs(s[i]);
q.push(make_pair(s[i],i));
}
suf[n]=0;
while(k--)
{
while(vis[q.top().second])q.pop();
ans-=q.top().first;
int now=q.top().second;
q.pop();
vis[pre[now]]=vis[suf[now]]=1;
if(pre[now]&&suf[now])
{
s[now]=s[pre[now]]+s[suf[now]]-s[now];
q.push(make_pair(s[now],now));
pre[now]=pre[pre[now]];
suf[now]=suf[suf[now]];
if(pre[now])
{
suf[pre[now]]=now;
}
if(suf[now])
{
pre[suf[now]]=now;
}
}
else
{
vis[now]=1;
pre[now]=pre[pre[now]];
suf[now]=suf[suf[now]];
if(pre[now])
{
suf[pre[now]]=suf[now];
}
if(suf[now])
{
pre[suf[now]]=pre[now];
}
}
}
printf("%lld",ans);
} 

BZOJ3502PA2012Tanie linie&BZOJ2288[POJ Challenge]生日礼物——模拟费用流+链表+堆的更多相关文章

  1. 【bzoj1150】&lbrack;CTSC2007&rsqb;数据备份Backup 模拟费用流&plus;链表&plus;堆

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

  2. BZOJ2151种树——模拟费用流&plus;链表&plus;堆

    题目描述 A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市*决定沿圆形广场外圈种一圈树.园林部门得到指令后,初步规划出n个种树的位置,顺时针编号1到n.并且每个位置都有一个美观度Ai,如果在这 ...

  3. &lbrack;bzoj2288&rsqb;&lbrack;POJ Challenge&rsqb;生日礼物

    用堆维护双向链表来贪心... 数据范围显然不容许O(nm)的傻逼dp>_<..而且dp光是状态就n*m个了..显然没法优化 大概就会想到贪心乱搞了吧...一开始想贪心地通过几段小的负数把正 ...

  4. 【BZOJ3502&sol;2288】PA2012 Tanie linie&sol;【POJ Challenge】生日礼物 堆&plus;链表(模拟费用流)

    [BZOJ3502]PA2012 Tanie linie Description n个数字,求不相交的总和最大的最多k个连续子序列. 1<= k<= N<= 1000000. Sam ...

  5. 贪心(模拟费用流):NOIP2011 观光公交

    [问题描述] 风景迷人的小城Y 市,拥有n 个美丽的景点.由于慕名而来的游客越来越多,Y 市特意安排了一辆观光公交车,为游客提供更便捷的交通服务.观光公交车在第0 分钟出现在1号景点,随后依次前往2. ...

  6. BZOJ4977&lbrack;Lydsy1708月赛&rsqb;跳伞求生——贪心&plus;堆&plus;模拟费用流

    题目链接: 跳伞求生 可以将题目转化成数轴上有$n$个人和$m$个房子,坐标分别为$a_{i}$和$b_{i}$,每个人可以进一个他左边的房子,每个房子只能进一个人.每个房子有一个收益$c_{i}$, ...

  7. &lbrack;UOJ455&rsqb;&lbrack;UER &num;8&rsqb;雪灾与外卖——堆&plus;模拟费用流

    题目链接: [UOJ455]雪灾与外卖 题目描述:有$n$个送餐员(坐标为$x_{i}$)及$m$个餐厅(坐标为$y_{i}$,权值为$w_{i}$),每个送餐员需要前往一个餐厅,每个餐厅只能容纳$c ...

  8. BZOJ4849&lbrack;Neerc2016&rsqb;Mole Tunnels——模拟费用流&plus;树形DP

    题目描述 鼹鼠们在底下开凿了n个洞,由n-1条隧道连接,对于任意的i>1,第i个洞都会和第i/2(取下整)个洞间有一条隧 道,第i个洞内还有ci个食物能供最多ci只鼹鼠吃.一共有m只鼹鼠,第i只 ...

  9. 【CF280D】 k-Maximum Subsequence Sum ,线段树模拟费用流

    昨天考试被教育了一波.为了学习一下\(T3\)的科技,我就找到了这个远古时期的\(cf\)题(虽然最后\(T3\)还是不会写吧\(QAQ\)) 顾名思义,这个题目其实可以建成一个费用流的模型.我们用流 ...

随机推荐

  1. jQuery中,&dollar;&lpar;&&num;39&semi;&num;main&&num;39&semi;&rpar; 与 document&period;getElementById&lpar;&&num;39&semi;main&&num;39&semi;&rpar;是什么样的关系-转

    $('#main')[0]和document.getElementById('main')两个一模一样.解释:$('#main'):是一个jquery写法,#main是一个过滤器表示方法,表示查找一个 ...

  2. ab做压力测试

    ab是apache 自带的一个压力测试的小工具,可用于接口简单的压力测试. 以下是AB的简要介绍 格式:ab [options] [http://]hostname[:port]/path 参数说明: ...

  3. codeforces -- 283A

    A. Cows and Sequence time limit per test 3 seconds memory limit per test 256 megabytes input standar ...

  4. uva10635 LCS映射转LIS

    题目给定 2个序列,要我们求LCS,但是序列的长度最长是250*250, LCS的时间复杂度是O(N*N),所以无法解决 我们可以第一个序列的数字,按位置,映射为1.2.3.4.5.6.7.8.9 那 ...

  5. 修改index&period;php 清空mylog1&period;txt

    进入编辑php文件vim index.php(无则新建) -->进入命令行模式--输入a(append)-->进入编辑模式-->编辑好-->esc退出编辑模式-->:q! ...

  6. My first essay

    今天是我开通博客第一天,从此开始了我的博客之路.为了实现成为程序猿的我,现在开始努力啦~今年大三,就读杭州电子科技大学,通信工程专业.现在在自学web前端,虽然与我就读专业并无多大相关,但是这是根据自 ...

  7. 《Linux就该这么学》第十七天课程

    想学Squid可以前往https://www.linuxprobe.com/chapter-16.html讲的非常细 Squid服务程序提供正向代理服务 Squid服务程序提供的反向代理模式

  8. Info - 信息分析思路概要

    信息分析要素 局部 --->整体 显性 --->隐性 表面 --->本质 割裂 --->联系 特殊 --->普遍 串行 --->并发 纵向 --->横向 单点 ...

  9. JAVA-错误The type BookServiceImpl must implement the inherited abstract method

    错误原因 :是因为class继承了其他的类,没有导入过来,选择add unimplemented methods进行解决

  10. 数论——算数基本定理 - HDU 4497 GCD and LCM

    GCD and LCM Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total ...