BZOJ 1150 CTSC2007 数据备份Backup 堆+馋
标题效果:给定一个长度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 堆+馋的更多相关文章
- 【链表】bzoj 1150: [CTSC2007]数据备份Backup
1150: [CTSC2007]数据备份Backup Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1136 Solved: 458[Submit] ...
- [BZOJ 1150] [CTSC2007] 数据备份Backup 【贪心 + 链表】
题目链接:BZOJ - 1150 题目分析 可以看出,我们选的 k 条边一定是相邻两点之间的线段.我们可以将每条边看成一个点,那么我们就是要在 n-1 个点中选出互不相邻的 k 个,使它们的和最小. ...
- bzoj 1150: [CTSC2007]数据备份Backup
Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家 ...
- bzoj 1150: [CTSC2007]数据备份Backup【链表+堆】
参考:http://blog.csdn.net/Regina8023/article/details/44158947 神奇的做法.题意相当于若干个数取不相邻的k个使最小.先把数组差分,len表示这段 ...
- BZOJ 1150 [CTSC2007]数据备份Backup(贪心+优先队列)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1150 [题目大意] 给出n个数,请你挑出k对(每个数不可重复选取),使得他们差的绝对值 ...
- 【BZOJ 1150】 1150: [CTSC2007]数据备份Backup (贪心+优先队列+双向链表)
1150: [CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设 ...
- 1150: [CTSC2007]数据备份Backup
1150: [CTSC2007]数据备份Backup https://lydsy.com/JudgeOnline/problem.php?id=1150 分析: 堆+贪心. 每次选最小的并一定是最优的 ...
- BZOJ1150 [CTSC2007]数据备份Backup 链表+小根堆
BZOJ1150 [CTSC2007]数据备份Backup 题意: 给定一个长度为\(n\)的数组,要求选\(k\)个数且两两不相邻,问最小值是多少 题解: 做一个小根堆,把所有值放进去,当选择一个值 ...
- bzoj1150 [CTSC2007]数据备份Backup 双向链表+堆
[CTSC2007]数据备份Backup Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2727 Solved: 1099[Submit][Stat ...
随机推荐
- Codeforces 474 F. Ant colony
线段树求某一段的GCD..... F. Ant colony time limit per test 1 second memory limit per test 256 megabytes inpu ...
- Android中使用JNI获得APK签名的哈希值
原地址:http://blog.csdn.net/i5suoi/article/details/19036975 最近在研究android应用中的安全问题,貌似只有将核心代码写到JNI底层才是最安全的 ...
- RGB與CIELAB色彩空間轉換
原地址:http://cg2010studio.wordpress.com/2012/10/02/rgb與cielab色彩空間轉換/ 之前有研究CIE L*a*b*色彩空間,現在想更進一步探討RGB色 ...
- Android菜鸟的成长笔记(27)——ViewPager的使用
ViewPager是Android 3.0以上能够使用的API. 一.ViewPager能干什么? 1.微信5.0中连带滑动用ViewPager能够轻松实现. 2.实现相似于新浪微博的导航引导界面. ...
- Linux中下载,压缩,解压等命令
查看是否和还有一台Linux机器相通命令:ssh 主机名@Ip地址 ,提示输入password.就可以查看远程文件的文件夹 下载远程机器上的文件:scp 主机名@Ip地址:/path/s ...
- Net Kafka
Net Kafka Kafka 协议实现中的内存优化 Jusfr 2016-04-18 08:28 阅读:241 评论:1 Kafka API: TopicMetadata Jusfr 201 ...
- Linux Shell脚本入门--grep命令详解
grep简介<摘自鸟哥,并加以整理.> grep (global search regular expression(RE) and print out the line,全面搜索正则表达 ...
- php反射类 ReflectionClass
什么是php反射类,顾名思义,能够理解为一个类的映射.举个样例: class fuc { //定义一个类static function ec() {echo '我是一个类';}}$cla ...
- 牛逼的验证码,printf返回值
牛逼的验证码,如下图, 结果是4321,为什么呢,主要是printf返回值问题?那么printf到底返回什么? 经查阅,printf的返回值是打印的字符个数,因此结果是4321就很明显了.
- IL来理解属性
IL来理解属性 阅读目录 概述: C#中如何定义一个属性 Student类 属性Name Main方法 实现get,set方法 性能 访问权限 回到最开始提出的问题 参考资料 .Net底层剖析目录 ...