BZOJ1150 [CTSC2007]数据备份Backup 贪心 堆
欢迎访问~原文出处——博客园-zhouzhendong
去博客园看该题解
题目传送门 - BZOJ1150
题意概括
数轴上面有一堆数字。
取出两个数字的代价是他们的距离。
现在要取出k对数,(一个数字被取出之后就不可再取),问最小代价。
题解
这题貌似哪里做过。
如果取了可以再取,那么我们肯定贪心的选择最短的。
于是我们考虑先把所有的n个点变成n - 1条线段,然后取这些线段。
我们贪心的来。
每次要取掉最短的线段,那么我们用一个堆来维护。
取掉最短的线段之后,我们删除它两端的线段,并修改其值为他 左边的 + 右边的 - 它自己。
那么下一次取这一条线段的时候,就巧妙的变成了取原先的这条线段的两端的线段。
这样就可以了。所以为了维护这个左右线段,我们要用上双向链表。
代码
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
using namespace std;
const int N=100000+5,Inf=1e9;
void read(int &x){
x=0;
char ch=getchar();
while (!('0'<=ch&&ch<='9'))
ch=getchar();
while ('0'<=ch&&ch<='9')
x=x*10+ch-48,ch=getchar();
}
int n,k,a[N],L[N],R[N],f[N],bh[N];
struct Seg{
int len,pos,bh;
bool operator < (const Seg a) const{
return len>a.len;
}
}s;
Seg new_Seg(int a,int b,int c){
Seg res;
res.len=a,res.pos=b,res.bh=c;
return res;
}
priority_queue <Seg> q;
void Delete(int pos){
if (pos==1||pos==n+1)
return;
f[pos]=1;
R[L[pos]]=R[pos];
L[R[pos]]=L[pos];
}
int main(){
read(n),read(k);
for (int i=1;i<=n;i++)
read(a[i]);
for (int i=n;i>1;i--)
a[i]-=a[i-1];
for (int i=1;i<=n+1;i++)
L[i]=i-1,R[i]=i+1;
a[1]=a[n+1]=Inf;
while (!q.empty())
q.pop();
memset(f,0,sizeof f);
memset(bh,0,sizeof bh);
for (int i=2;i<=n;i++)
q.push(new_Seg(a[i],i,0));
int ans=0;
while (k--){
s=q.top();
while (f[s.pos]||bh[s.pos]!=s.bh)
q.pop(),s=q.top();
ans+=s.len;
int pos=s.pos,le=L[pos],ri=R[pos];
q.push(new_Seg(a[pos]=a[le]+a[ri]-a[pos],pos,++bh[pos]));
Delete(le);
Delete(ri);
}
printf("%d",ans);
return 0;
}
BZOJ1150 [CTSC2007]数据备份Backup 贪心 堆的更多相关文章
- bzoj1150 [CTSC2007]数据备份Backup 双向链表+堆
[CTSC2007]数据备份Backup Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2727 Solved: 1099[Submit][Stat ...
- BZOJ1150 [CTSC2007] 数据备份Backup 贪心_堆_神题
Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家 ...
- BZOJ1150 [CTSC2007]数据备份Backup 【堆 + 链表】
题目 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家中尽享计算机游戏的 ...
- BZOJ1150 [CTSC2007]数据备份Backup 链表+小根堆
BZOJ1150 [CTSC2007]数据备份Backup 题意: 给定一个长度为\(n\)的数组,要求选\(k\)个数且两两不相邻,问最小值是多少 题解: 做一个小根堆,把所有值放进去,当选择一个值 ...
- 【BZOJ1150】[CTSC2007]数据备份Backup 双向链表+堆(模拟费用流)
[BZOJ1150][CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此 ...
- BZOJ1150[CTSC2007]数据备份Backup——模拟费用流+堆+链表
题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家中尽享计算机游 ...
- bzoj1150: [CTSC2007]数据备份Backup
题目大意: 在n个点中,选出k对相邻的互不相同的点,使k段距离的总和最小. 贪心,双向链表. 首先,点之间的距离是动态的,所以要用堆来维护. 每次都选择最近的点.但因为其他情况,可能最终不会选择这 ...
- 【BZOJ 1150】 1150: [CTSC2007]数据备份Backup (贪心+优先队列+双向链表)
1150: [CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设 ...
- 【链表】bzoj 1150: [CTSC2007]数据备份Backup
1150: [CTSC2007]数据备份Backup Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1136 Solved: 458[Submit] ...
随机推荐
- fcn16s
- luogu P4036 [JSOI2008]火星人
传送门 很久以前xzz大佬就喊我做这题,结果现在才做qwq 因为要在序列中插入,所以直接用\(Splay\)维护这个串的哈希值,插入就直接把那个点插♂进去,修改就把点旋到根,然后修改和pushup,询 ...
- 第16月第31天 mongo
1. 94 brew install mongodb 95 cd ~ 96 cd Desktop/web/ 97 ls 98 mkdir mongo 99 cd mongo/ 100 ...
- Python人工智能之路 - 第四篇 : jieba gensim 最好别分家之最简单的相似度实现
简单的问答已经实现了,那么问题也跟着出现了,我不能确定问题一定是"你叫什么名字",也有可能是"你是谁","你叫啥"之类的,这就引出了人工智能 ...
- idea的起步配置
工欲善其事,必先利其器 1.安装 https://www.jetbrains.com/idea/download/#section=windows 可以选择不同平台的安装包,版本一般Ultimate, ...
- mysql 案例 ~ pt-xtrabackup 使用
一 简介:学习innobackup工具使用 二 功能: 备份全库/单库/单表 三 常用命令 一 全库 目的 每天日常备份 备份 innobackupex --defaults-file=/etc ...
- js数组的操作push,pop,shift,unshift
push(args)可以每次压入多个元素,并返回更新后的数组长度. var oldArr=[1,2,3]; alert(oldArr.push(4,[5,6]))–>5(这里只会将[5,6]当做 ...
- Linq基于两个属性的分组
1.需求 我们看下面的定义 #region 学生类 /// <summary> /// 学生类 /// </summary> class Student { /// <s ...
- linux 高级字符设备驱动 ioctl操作介绍 例程分析实现【转】
转自:http://my.oschina.net/u/274829/blog/285014 1,ioctl介绍 ioctl控制设备读写数据以及关闭等. 用户空间函数原型:int ioctl(int f ...
- Sql 插入自定义主键
在遇到数据库设计是自增的主键,且需要插入自定义的主键Id时,这个时候如果直接Insert的话,将会发生错误,错误提示信息: 当 IDENTITY_INSERT 设置为 OFF 时,不能为表 'XXX' ...