[CTSC2007][APIO2007]数据备份Backup
题目:BZOJ1150、codevs1615、洛谷P3620
题目大意:有n个点,k条链,每个点离原点有一定的距离。要你用k条链连接2k个点,使得k条链的长度最短。
解题思路:毕竟是CTSC级别的题目,很难找出正确算法。在网上翻阅了很多资料后,终于理解了此题的正确算法。orz
正确算法为:贪心+链表+堆。
首先每次肯定是链相邻的2个点,所以我们先把相邻2个点的差值求出来,得到有n-1个数的数列。
然后问题就变成“在这个数列中寻找k个互不相邻的点,使得它们的和最小”。
我们把所有的数扔进一个堆里,每次贪心找出最小的数,在答案里把它加上。
这时就会出现一个问题:假设我们贪心出了第i个数,那么有可能选第i-1个数和第i+1个数最终的结果优于选第i个数。
所以我们每次贪心时,把找到的那个数的前一个数和后一个数删掉,把“前一个数+后一个数-原数”的值扔进堆里,如果这个数被选,相当于选了前一个数和后一个数而不选原数。
而链表记录的是每个数的前一个和后一个。详见代码第32~35行。
在删数时,并不需要在堆里找到这个数,只需把它的值改为inf就行了。详见代码第36行。
C++ Code:
#include<cstdio>
#include<ext/pb_ds/priority_queue.hpp>
const int inf=int(1000000000*1.3);
using namespace std;
struct shuju{
int dis,num;
shuju(int d,int n):dis(d),num(n){}
bool operator<(const shuju& rhs)const{return dis>rhs.dis;}
};
__gnu_pbds::priority_queue<shuju,less<shuju>,__gnu_pbds::pairing_heap_tag>h;
int n,k,dis[100005],pre[100005],nxt[100005];
int main(){
scanf("%d%d",&n,&k);
int x,y;
scanf("%d",&x);
for(int i=2;i<=n;i++){
scanf("%d",&y);
dis[i]=y-x;x=y;
h.push(shuju(dis[i],i));
pre[i]=i-1;nxt[i]=i+1;
}
int ans=0;
pre[2]=nxt[n]=0;
while(k--){
while(h.top().dis!=dis[h.top().num])h.pop();
int k=h.top().num;
int l=pre[k],r=nxt[k];
h.pop();
ans+=dis[k];
if(l&&r)dis[k]=dis[l]+dis[r]-dis[k];else
dis[k]=inf;
pre[nxt[r]]=k;
nxt[pre[l]]=k;
nxt[k]=nxt[r];
pre[k]=pre[l];
dis[l]=dis[r]=inf;
h.push(shuju(dis[k],k));
}
printf("%d\n",ans);
return 0;
}
[CTSC2007][APIO2007]数据备份Backup的更多相关文章
- 【BZOJ】【1150】【CTSC2007】数据备份Backup
堆/贪心 一共N-1个元素……用堆维护最大值,取了第x个元素以后,插入v[x-1]+v[x+1]-v[x]这个元素,如果再取这个新元素就表示不取x,而取x-1和x+1……大概就是这种“带反悔”的思路吧 ...
- 【链表】bzoj 1150: [CTSC2007]数据备份Backup
1150: [CTSC2007]数据备份Backup Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1136 Solved: 458[Submit] ...
- bzoj1150 [CTSC2007]数据备份Backup 双向链表+堆
[CTSC2007]数据备份Backup Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2727 Solved: 1099[Submit][Stat ...
- 1150: [CTSC2007]数据备份Backup
1150: [CTSC2007]数据备份Backup https://lydsy.com/JudgeOnline/problem.php?id=1150 分析: 堆+贪心. 每次选最小的并一定是最优的 ...
- 【BZOJ 1150】 1150: [CTSC2007]数据备份Backup (贪心+优先队列+双向链表)
1150: [CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设 ...
- 【BZOJ1150】[CTSC2007]数据备份Backup 双向链表+堆(模拟费用流)
[BZOJ1150][CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此 ...
- BZOJ1150 [CTSC2007]数据备份Backup 链表+小根堆
BZOJ1150 [CTSC2007]数据备份Backup 题意: 给定一个长度为\(n\)的数组,要求选\(k\)个数且两两不相邻,问最小值是多少 题解: 做一个小根堆,把所有值放进去,当选择一个值 ...
- bzoj 1150: [CTSC2007]数据备份Backup
Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家 ...
- 【bzoj1150】[CTSC2007]数据备份Backup 模拟费用流+链表+堆
题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家中尽享计算机游戏 ...
随机推荐
- Unity 手机屏幕翻转问题 横屏
1920*1080的图在1080*1920的设备上观看效果: 如果要做横屏游戏,就要改Build中的Player Settings,强制左旋转或右旋转,默认是Auto 垂直于地面的手机在横屏下分辨率是 ...
- C语言基本语法——结构体、联合和枚举
一.结构体 1.什么是结构体 2.结构体语法格式 3.结构体所占内存空间 4.结构体成员赋值 二.联合 1.什么是联合 2.联合语法格式 三.枚举 1.什么是枚举 2.枚举语法格式 一.结构体 1.什 ...
- 【BZOJ1396】识别子串 - 后缀自动机+线段树
题意: Description Input 一行,一个由小写字母组成的字符串S,长度不超过10^5 Output L行,每行一个整数,第i行的数据表示关于S的第i个元素的最短识别子串有多长. 题解: ...
- CSS布局总结(三)
前言:今天学的有点少,主要是有点迷.... 这是昨天没写的 一.水平居中 .parent{ text-aglin:center; } .child{ display:inline-block; } . ...
- Vue 做项目经验
Vue 做项目经验 首先需要知道最基本的东西是: Vue 项目打包:npm run build Vue生成在网页上看的端口:npm run dev 修改端口号的地方在: config文件夹下index ...
- 8:30+1.5小时,返回时间格式的 php函数
一个实用的自定义函数 /** * 传入8:30格式的开始时间,和小数形式的小时长度,返回结束时间 * @param [type] $start [description] 8:30 * @param ...
- 基本配置及安全级别security-level
interface GigabitEthernet0/0 nameif outside //指定接口名称 security-level 0 //安全级别设置 ip address 1.1.1.2 ...
- Qt实战之酷狗音乐
此项目仅仅实现实现基本功能: 界面的模仿. 歌词功能的实现.歌曲在线试听和下载. 专辑写真的播放. 在线歌词搜索.以及主要的button功能. 界面没有採用设计器. 所有手写规划.这里先放出效果图. ...
- 题目1437:To Fill or Not to Fill(贪心算法)
题目描写叙述: With highways available, driving a car from Hangzhou to any other city is easy. But since th ...
- 16、sockect
一.局域网因特网 服务器是指提供信息的计算机或程序,客户机是指请求信息的计算机或程序,而网络用于连接服务器与客户机,实现两者之间的通信.但有时在某个网络中很难将服务器和客户机区分开.我们通常说的“局域 ...