博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ3502PA2012Tanie linie&BZOJ2288[POJ Challenge]生日礼物——模拟费用流+链表+堆
阅读量:6397 次
发布时间:2019-06-23

本文共 1892 字,大约阅读时间需要 6 分钟。

题目描述

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

 1<= k<= N<= 1000000。

输入

输出

样例输入

5 2
7 -3 4 -9 5

样例输出

13
 
根据贪心的思想可以知道对于一段连续的正数或负数一定是一起选或者一起不选,那么我们可以将原序列连续的正数或负数缩成一个数,并将中间的$0$及两端的负数去掉,这样序列就变成了正负正负……负正的形式。先贪心地将所有正数选取,如果正数个数$\le k$直接输出正数和就是最优方案,否则我们需要去掉一些正数或选取一些两个正数之间的负数。可以发现无论是去掉正数还是选取负数,答案减少的量都是这个数的绝对值。而根据贪心的原则,如果去掉一个正数一定不会再选取相邻的两个负数,同样选取一个负数一定不会去掉相邻的两个正数。假设序列有$m$个正数,那么问题就变成了给出一个序列(每个数权值为之前的正负序列对应数的绝对值),选出$m-k$个数且不能选取相邻的数使选取数的总和最小,做法和相同:维护所有数的小根堆,每次取出堆顶$b$计入答案并将与堆顶相邻的两个数$a,c$删除,将权值为$a+c-b$的一个新数插入到原来堆顶的位置。最后用双向链表维护相邻关系。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long#define pr pair
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
,greater
>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);} 

转载于:https://www.cnblogs.com/Khada-Jhin/p/10429517.html

你可能感兴趣的文章
【收藏】QCIF、 CIF、2CIF、DCIF、D1(4CIF)格式介绍
查看>>
hdu 3836 Equivalent Sets (tarjan缩点)
查看>>
一些iOS高效开源类库(转)
查看>>
JAVA编程心得-JAVA实现CRC-CCITT(XMODEM)算法
查看>>
C# DES加密
查看>>
浅谈Oracle分区表之范围分区
查看>>
IBM Tivoli NetView网管软件实战
查看>>
IPSec逻辑体系架构
查看>>
Exchange 2013部署系列之(六)配置邮件流和客户端访问
查看>>
List of Free Programming books
查看>>
思考Android架构(二):像Android框架,如何(How-to)吸引开发者来使用它呢?
查看>>
windows 8 应用小技巧(36-40)
查看>>
8. package 和 import
查看>>
在html中,怎么获取当前页面body的高度,body是没有设置高度的,但是里面有内容...
查看>>
IDC云时代神兵利器-还在等什么!是IDC就可以云主机
查看>>
把 Array 转换成 Map
查看>>
MyBatis入门学习
查看>>
ASA防火墙IPSEC
查看>>
djangostart01
查看>>
NoSql之深入浅出redis
查看>>