标题效果:给定一个长度n−1的序列,要求选出k个不相邻的数使得和最小

费用流显然能跑。并且显然过不去- -

考虑用堆模拟费用流

一个错误的贪心是每次取最小。这样显然过不去例子

我们把【每次取最小】改为【每次选择一个区间取反】。用堆来维护这些区间就可以

每次取出最小的区间,然后将两边合并

(比方如今堆里有[1,3][4,4][5,5])这三个区间,我取走了[4,4]并计入答案。那么我删除[1,3]和[5,5]这两个区间,并增加[1,5]这个区间,权值为[1,3]的权值+[5,5]的权值-[4,4]的权值

因为是费用流所以不用考虑边界问题 直接把[0,0]和[n+1,n+1]设为INF就可以

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 100100
using namespace std;
struct abcd{
int x,val;
abcd() {}
abcd(int _,int __):
x(_),val(__) {}
bool operator < (const abcd &a) const
{
if( val != a.val )
return val > a.val ;
return x < a.x ;
}
bool operator == (const abcd &a) const
{
return x==a.x && val==a.val ;
}
};
namespace Heap{
priority_queue<abcd> heap,del_mark;
void Insert(abcd x)
{
heap.push(x);
}
void Delete(abcd x)
{
del_mark.push(x);
}
void Pop()
{
while( del_mark.size() && heap.top()==del_mark.top() )
heap.pop(),del_mark.pop();
heap.pop();
}
abcd Top()
{
while( del_mark.size() && heap.top()==del_mark.top() )
heap.pop(),del_mark.pop();
return heap.top();
}
}
int n,k,ans,a[M],val[M];
namespace Union_Find_Set{
int fa[M],rank[M],l[M],r[M];
int Find(int x)
{
if(!fa[x]||fa[x]==x)
return fa[x]=x;
return fa[x]=Find(fa[x]);
}
void Union(int x,int y)
{
int _l=l[x=Find(x)];
int _r=r[y=Find(y)];
if(rank[x]>rank[y])
swap(x,y);
if(rank[x]==rank[y])
++rank[y];
fa[x]=y;
l[y]=_l;r[y]=_r;
}
}
int main()
{
using namespace Union_Find_Set;
int i;
cin>>n>>k;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=1;i<=n+1;i++)
l[i]=i-1,r[i]=i+1;
Heap::Insert(abcd(1,val[1]=0x3f3f3f3f));
Heap::Insert(abcd(n+1,val[n+1]=0x3f3f3f3f));
for(i=2;i<=n;i++)
Heap::Insert(abcd(i,val[i]=a[i]-a[i-1]));
for(i=1;i<=k;i++)
{
abcd temp=Heap::Top();Heap::Pop();
ans+=temp.val;
int _l=Find(l[temp.x]),_r=Find(r[temp.x]);
Heap::Delete(abcd(_l,val[_l]));
Heap::Delete(abcd(_r,val[_r]));
temp.val=val[_l]+val[_r]-val[temp.x];
Union(_l,temp.x);
Union(temp.x,_r);
temp.x=Find(temp.x);
Heap::Insert(temp);
val[temp.x]=temp.val;
}
cout<<ans<<endl;
return 0;
}

版权声明:本文博主原创文章,博客,未经同意不得转载。

BZOJ 1150 CTSC2007 数据备份Backup 堆+馋的更多相关文章

  1. 【链表】bzoj 1150: [CTSC2007]数据备份Backup

    1150: [CTSC2007]数据备份Backup Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1136  Solved: 458[Submit] ...

  2. [BZOJ 1150] [CTSC2007] 数据备份Backup 【贪心 + 链表】

    题目链接:BZOJ - 1150 题目分析 可以看出,我们选的 k 条边一定是相邻两点之间的线段.我们可以将每条边看成一个点,那么我们就是要在 n-1 个点中选出互不相邻的 k 个,使它们的和最小. ...

  3. bzoj 1150: [CTSC2007]数据备份Backup

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

  4. bzoj 1150: [CTSC2007]数据备份Backup【链表+堆】

    参考:http://blog.csdn.net/Regina8023/article/details/44158947 神奇的做法.题意相当于若干个数取不相邻的k个使最小.先把数组差分,len表示这段 ...

  5. BZOJ 1150 [CTSC2007]数据备份Backup(贪心+优先队列)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1150 [题目大意] 给出n个数,请你挑出k对(每个数不可重复选取),使得他们差的绝对值 ...

  6. 【BZOJ 1150】 1150: [CTSC2007]数据备份Backup (贪心+优先队列+双向链表)

    1150: [CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设 ...

  7. 1150: [CTSC2007]数据备份Backup

    1150: [CTSC2007]数据备份Backup https://lydsy.com/JudgeOnline/problem.php?id=1150 分析: 堆+贪心. 每次选最小的并一定是最优的 ...

  8. BZOJ1150 [CTSC2007]数据备份Backup 链表+小根堆

    BZOJ1150 [CTSC2007]数据备份Backup 题意: 给定一个长度为\(n\)的数组,要求选\(k\)个数且两两不相邻,问最小值是多少 题解: 做一个小根堆,把所有值放进去,当选择一个值 ...

  9. bzoj1150 [CTSC2007]数据备份Backup 双向链表+堆

    [CTSC2007]数据备份Backup Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2727  Solved: 1099[Submit][Stat ...

随机推荐

  1. 安装Oracle JDK 7.0与8.0 for Mac OS X后Eclipse启动报错的解决之道

    启动 Eclipse 时,直接报错The JVM shared library "/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Cont ...

  2. 【 D3.js 入门系列 --- 8 】 对话操作(事件)

    本人的个人博客为: www.ourd3js.com csdn博客为: blog.csdn.net/lzhlzz 转载请注明出处,谢谢. 这一节介绍怎样进行对话的操作,如鼠标单击,鼠标滑过等. 对一个被 ...

  3. LINUX专题之操作系统字符集

    原创作品,出自 "深蓝的blog" 博客,欢迎转载.转载时请务必注明下面出处,否则追究版权法律责任. 深蓝的blog: http://blog.csdn.net/huangyanl ...

  4. Android ----制作自己的Vendor

    Android源代码使用一个可定制的编译系统来生成 特定的,针对自己硬件平台的Android系统,比方不使用缺省的out/target/prodect/generic文件夹, 本文档简介了这个编译系统 ...

  5. Cocos2dx 3.0 过渡篇(二十六)C++11多线程std::thread的简单使用(上)

    昨天练车时有一MM与我交替着练,聊了几句话就多了起来,我对她说:"看到前面那俩教练没?老色鬼两枚!整天调戏女学员."她说:"还好啦,这毕竟是他们的乐趣所在,你不认为教练每 ...

  6. Java 模拟队列(一般队列、双端队列、优先级队列)

    队列: 先进先出,处理类似排队的问题,先排的.先处理,后排的等前面的处理完了,再处理 对于插入和移除操作的时间复杂度都为O(1).从后面插入,从前面移除 双端队列: 即在队列两端都能够insert和r ...

  7. zoj3640(概率dp)

    题目连接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4808 题意: 一个吸血鬼,每次可以随机的选择n个洞中的任意一个,如果 ...

  8. poj3414(bfs)

    题目链接:http://poj.org/problem?id=3414 题意:给你两个容器 A  B 问是否能够经过有限的步骤倒水,得到容量为 C 的水,输出最小的步数,同时输出每一步的操作.如果不能 ...

  9. poj3126(bfs)

    题目链接:http://poj.org/problem?id=3126 题意:给两个四位数n,m,将n变成m需要多少步,要求每次只能改变n的某一位数,即改变后的数与改变前的数只有一位不同,且每次改变后 ...

  10. mixpanel实验教程(2)

    六.发送邮件和推送通知 选择该用户前面的 checkbox,点击 Send A Notification button,从下拉列表中选择 Email Message/Push Notifiaction ...