【BZOJ3502/2288】PA2012 Tanie linie/【POJ Challenge】生日礼物 堆+链表(模拟费用流)
【BZOJ3502】PA2012 Tanie linie
Description
n个数字,求不相交的总和最大的最多k个连续子序列。
1<= k<= N<= 1000000。
Sample Input
7 -3 4 -9 5
Sample Output
题解:跟1150和2151差不多。
我们先做一些预处理,因为连续的正数和连续的负数一定是要么都选要么都不选,所以可以将它们合并成一个数,同时区间中的零以及左右两端的负数没有意义,可以将它们删掉。然后我们得到的序列就变成:正-负-正-...-负-正。
然后我们贪心的把所有正数都选了,如果正数的部分<=k,那么直接取光即可,否则,我们还要将我们的子串个数减少一些。如何减少呢?1:将某个正数由选变为不选。2.将某个负数由不选变为选。我们发现,这两种情况都会使答案减少:那个数的绝对值,所以我们可以用堆维护所有数的绝对值,然后每次都贪心的选取绝对值小的。
但是直接贪心肯定不行,我们要模拟费用流的过程,也就是加入一个反悔操作。发现:如果对一个整数进行了1操作,那么我们就无法对它相邻的负数进行2操作;如果对一个负数进行了2操作,那么我们就无法对它相邻的正数进行1操作。所以我们再堆中删掉与它相邻的点。那么怎么反悔呢?如果当前是b,b的前驱是a,后继是c,那么向堆中加入a+c-b。如果再次选择了a+c-b,意味着我们撤销了对b的操作,而是对a和c进行操作,这样就和费用流是一样的了。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <utility>
#include <algorithm>
#define mp(A,B) make_pair(A,B)
using namespace std;
typedef long long ll;
const int maxn=1000010;
int n,m,k;
ll ans;
ll v[maxn],p[maxn];
int pre[maxn],nxt[maxn],del[maxn];
typedef pair<ll,int> pli;
priority_queue<pli> q;
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int main()
{
n=rd(),m=rd();
int i,a,b,tp=0;
for(i=1;i<=n;i++)
{
v[i]=rd();
if(v[i]>0)
{
ans+=v[i];
if(p[tp]>0) p[tp]+=v[i];
else p[++tp]=v[i];
}
if(v[i]<0)
{
if(p[tp]<=0) p[tp]+=v[i];
else p[++tp]=v[i];
}
}
if(p[tp]<=0) tp--;
n=tp;
if((n+1)>>1<=m)
{
printf("%lld\n",ans);
return 0;
}
m=((n+1)>>1)-m;
for(i=1;i<=n;i++) p[i]=abs(p[i]),q.push(mp(-p[i],i)),pre[i]=i-1,nxt[i]=(i<n)?(i+1):0;
while(m--)
{
while(del[q.top().second]) q.pop();
ans+=q.top().first,i=q.top().second,q.pop();
a=pre[i],b=nxt[i],del[a]=del[b]=1;
if(a&&b)
{
pre[i]=pre[a],nxt[i]=nxt[b];
if(pre[i]) nxt[pre[i]]=i;
if(nxt[i]) pre[nxt[i]]=i;
p[i]=p[a]+p[b]-p[i],q.push(mp(-p[i],i));
}
else
{
pre[i]=pre[a],nxt[i]=nxt[b];
if(pre[i]) nxt[pre[i]]=nxt[i];
if(nxt[i]) pre[nxt[i]]=pre[i];
del[i]=1;
}
}
printf("%lld",ans);
return 0;
}
【BZOJ3502/2288】PA2012 Tanie linie/【POJ Challenge】生日礼物 堆+链表(模拟费用流)的更多相关文章
- POJ 3686 The Windy's (费用流)
[题目链接] http://poj.org/problem?id=3686 [题目大意] 每个工厂对于每种玩具的加工时间都是不同的, 并且在加工完一种玩具之后才能加工另一种,现在求加工完每种玩具的平均 ...
- BZOJ3502PA2012Tanie linie&BZOJ2288[POJ Challenge]生日礼物——模拟费用流+链表+堆
题目描述 n个数字,求不相交的总和最大的最多k个连续子序列. 1<= k<= N<= 1000000. 输入 输出 样例输入 5 2 7 -3 4 -9 5 样例输出 13 根据 ...
- bzoj3502[PA2012]Tanie Linie(最大k区间和)
题意:给定一个长为n的数列,要求选出最多k个不相交的区间(可以不选),使得选中的数字之和最大.(1<=k<=n<=1000000)分析:首先我们通过预处理对问题做一些简化.原序列中的 ...
- BZOJ 2288: 【POJ Challenge】生日礼物 堆&&链表
就是堆+链表,十分像 数据备份 对吧? 把相邻的正数和相邻的负数合并成一整个正数块和负数块,最后只剩一些交替相间的正块与负块了吧? 显然,正块的个数<=m时,全部选走就获得了最大权值,否则我们可 ...
- BZOJ2288:[POJ Challenge]生日礼物——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=2288 ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1, A2, . ...
- BZOJ2288:[POJ Challenge]生日礼物
浅谈堆:https://www.cnblogs.com/AKMer/p/10284629.html 题目传送门:https://lydsy.com/JudgeOnline/problem.php?id ...
- [bzoj2288][POJ Challenge]生日礼物
用堆维护双向链表来贪心... 数据范围显然不容许O(nm)的傻逼dp>_<..而且dp光是状态就n*m个了..显然没法优化 大概就会想到贪心乱搞了吧...一开始想贪心地通过几段小的负数把正 ...
- 【BZOJ】3502 PA2012 Tanie linie
[算法]贪心,一般DP [题解] --- 胡策k≤10的环状DP做法: 1.钦定法:先确定第一位(可能和第n位)的状态,然后后面正常做DP,显然正确答案是一定会被记录的,因为从整体上看不会有影响. 2 ...
- POJ 2175:Evacuation Plan(费用流消圈算法)***
http://poj.org/problem?id=2175 题意:有n个楼,m个防空洞,每个楼有一个坐标和一个人数B,每个防空洞有一个坐标和容纳量C,从楼到防空洞需要的时间是其曼哈顿距离+1,现在给 ...
随机推荐
- 虚拟机oracle virtualbox 上安装centos6.5 网络设置
上篇文章写到,在虚拟机上安装centos6.5,结果依照文章非常顺利的安装了,可是用yum安装软件的时候.报错,源有问题,不能下载,然后ping一下摆渡.非常悲催 dns解析不了,cat /etc/r ...
- python中的ord,chr函数
chr().unichr()和ord() chr()函数用一个范围在range(256)内的(就是0-255)整数作参数,返回一个对应的字符.unichr()跟它一样,只不过返回的是Unicode字符 ...
- 在OpenErp的配置文件中为数据库密码加密
openerp连接数据库的用户名和密码可以命令行给出, 也可以设置在配置文件中, 如下例所示: db_user = openerp db_password = laoliu 因为它使用了明文的密码 ...
- Android基于UDP的局域网聊天通信
代码地址如下:http://www.demodashi.com/demo/12057.html 记得把这几点描述好咯:代码实现过程 + 项目文件结构截图 + 演示效果 1. 开发环境 1.1 开发工具 ...
- VIM-不常用或不知道的技巧
cc 清除一行 并在本行编辑, 同理 cw :32,65d 多行删除 g/pattern/d 删除包含特定字符的行 v/pattern/d 删除不包含指定字符的行 等同于 g!/pattern/d y ...
- spring学习笔记(四)
1.aop编程 a.前置通知 .... <!-- 配置被代理的对象 --> <bean id="test1Service" class="com. ...
- html table表格导出excel的方法 html5 table导出Excel HTML用JS导出Excel的五种方法 html中table导出Excel 前端开发 将table内容导出到excel HTML table导出到Excel中的解决办法 js实现table导出Excel,保留table样式
先上代码 <script type="text/javascript" language="javascript"> var idTmr; ...
- STM32 通用T2、T3、T4、T5定时器详解
定时器初始化配置 void TIM3_Configuration(void)//1MS { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_DeI ...
- 关于top按钮的网页设置
方法一: 直接用html实现,没有缓冲的效果,直接彪到顶部. HTMl: <a id="return-top" href="#top"> <s ...
- UML类图详解_关联关系_多对一
首先先来明确一个概念,即多重性.什么是多重性呢?多重性是指两个对象之间的链接数目,表示法是“下限...上限”,最小数据为零(0),最大数目为没有设限(*),如果仅标示一个数目级上下限相同. 实际在UM ...