[CTSC2007]数据备份Backup (贪心)
题面
Description
你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份。然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家中尽享计算机游戏的乐趣。已知办公楼都位于同一条街上。你决定给这些办公楼配对(两个一组)。每一对办公楼可以通过在这两个建筑物之间铺设网络电缆使得它们可以互相备份。然而,网络电缆的费用很高。当地电信公司仅能为你提供 K 条网络电缆,这意味着你仅能为 K 对办公楼(或总计2K个办公楼)安排备份。任一个办公楼都属于唯一的配对组(换句话说,这 2K 个办公楼一定是相异的)。此外,电信公司需按网络电缆的长度(公里数)收费。因而,你需要选择这 K 对办公楼使得电缆的总长度尽可能短。换句话说,你需要选择这 K 对办公楼,使得每一对办公楼之间的距离之和(总距离)尽可能小。下面给出一个示例,假定你有 5 个客户,其办公楼都在一条街上,如下图所示。这 5 个办公楼分别位于距离大街起点 1km, 3km, 4km, 6km 和 12km 处。电信公司仅为你提供 K=2 条电缆。

上例中最好的配对方案是将第 1 个和第 2 个办公楼相连,第 3 个和第 4 个办公楼相连。这样可按要求使用 K=2 条电缆。第 1 条电缆的长度是 3km-1km=2km ,第 2 条电缆的长度是 6km-4km=2km。这种配对方案需要总长 4km 的网络电缆,满足距离之和最小的要求。
Input
第一行包含整数 n 和 k
其中 n(2 ≤ n ≤ 100 000)表示办公楼的数目,k(1 ≤ k ≤ n/2)表示可利用的网络电缆的数目。
接下来的 n 行每行仅包含一个整数(0 ≤ s ≤ 1 000 000 000),表示每个办公楼到大街起点处的距离。
这些整数将按照从小到大的顺序依次出现。
Output
输出应由一个正整数组成,给出将 2K 个相异的办公楼连成 k 对所需的网络电缆的最小总长度。
Sample Input
5 2
1
3
4
6
12
Sample Output
4
题解
首先,选的每一对楼肯定是相邻的两幢,所以,题意转化为在原数组的差分数组上选
k
k
k 个不相邻的数,使得总和最小。
然后,我发现它不能直接转化成拟阵,因为不满足交换性,也就是中间选的数会使得两边相邻的数不能被选。
于是我们用了一个类似反悔贪心的做法:
先找到差分数组中最小的一个,拿出来,设其为第
i
i
i 个数,那么接下来,可以证明
i
−
1
i-1
i−1 和
i
+
1
i+1
i+1 要么不选,要么同时选。反证法就行,若只选其中一个,同时
i
i
i 不能被选,这一定不如选
i
i
i 更优。
那么,
i
−
1
i-1
i−1 和
i
+
1
i+1
i+1 ——选
i
i
i 能影响到的所有位置——就是绑定在一起了,要么不选他们,保留
i
i
i ,选择的总数不变,要么选择它们,撤销掉
i
i
i ,选择的总数+1,同时影响
i
−
2
i-2
i−2 和
i
+
2
i+2
i+2 。
怎么看,我们都可以把
i
−
1
,
i
,
i
+
1
i-1,i,i+1
i−1,i,i+1 三个位置删掉,再在原位置插入一个
S
i
−
1
+
S
i
+
1
−
S
i
S_{i-1}+S_{i+1}-S_i
Si−1+Si+1−Si ,来转换这个复杂的过程。
最后就剩模拟了,
有自虐倾向精益求精 的人,可以打个平衡树模拟,讲效率 的人,可以打优先队列+链表。
CODE
我自诩精神正常
#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<ctime>
#include<queue>
#include<vector>
#include<bitset>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 100005
#define LL long long
#define DB double
#define ENDL putchar('\n')
#define lowbit(x) (-(x) & (x))
#define FI first
#define SE second
#define eps (1e-9)
#define SQ 447
LL read() {
LL f=1,x=0;char s = getchar();
while(s < '0' || s > '9') {if(s=='-')f = -f;s = getchar();}
while(s >= '0' && s <= '9') {x=x*10+(s-'0');s = getchar();}
return f*x;
}
void putpos(LL x) {
if(!x) return ;
putpos(x/10); putchar('0'+(x%10));
}
void putnum(LL x) {
if(!x) putchar('0');
else if(x < 0) putchar('-'),putpos(-x);
else putpos(x);
}
const int MOD = 1000000007;
int n,m,s,o,k;
LL a[MAXN];
struct it{
int x;LL s;it(){x=s=0;}
it(int X,LL S){x=X;s=S;}
};
bool operator < (it a,it b) {return a.s < b.s;}
bool operator > (it a,it b) {return b < a;}
priority_queue<it,vector<it>,greater<it> > b;
int nl[MAXN],nr[MAXN];
bool f[MAXN];
void del(int x) {
int s = nl[x],o = nr[x];
nr[s] = o; nl[o] = s;
f[x] = 1; return ;
}
int main() {
n = read(); k = read();
for(int i = 1;i <= n;i ++) {
a[i] = read();
}
for(int i = 1;i < n;i ++) {
a[i] = a[i+1]-a[i];
nl[i] = i-1; nr[i] = i+1;
b.push(it(i,a[i]));
}
a[0] = a[n] = 1e16;
LL ans = 0;
for(int i = 1;i <= k;i ++) {
it t = b.top();b.pop();
while(f[t.x]) t = b.top(),b.pop();
ans += t.s;
s = nl[t.x]; o = nr[t.x];
a[t.x] = a[s] + a[o] - t.s;
b.push(it(t.x,a[t.x]));
del(s); del(o);
}
printf("%lld\n",ans);
return 0;
}
[CTSC2007]数据备份Backup (贪心)的更多相关文章
- BZOJ1150 [CTSC2007] 数据备份Backup 贪心_堆_神题
Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家 ...
- BZOJ1150 [CTSC2007]数据备份Backup 贪心 堆
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1150 题意概括 数轴上面有一堆数字. 取出两个数字的代价是他们的距离. 现在要取出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] ...
- 1150: [CTSC2007]数据备份Backup
1150: [CTSC2007]数据备份Backup https://lydsy.com/JudgeOnline/problem.php?id=1150 分析: 堆+贪心. 每次选最小的并一定是最优的 ...
- bzoj1150 [CTSC2007]数据备份Backup 双向链表+堆
[CTSC2007]数据备份Backup Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2727 Solved: 1099[Submit][Stat ...
- 【BZOJ1150】[CTSC2007]数据备份Backup 双向链表+堆(模拟费用流)
[BZOJ1150][CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此 ...
- BZOJ1150 [CTSC2007]数据备份Backup 链表+小根堆
BZOJ1150 [CTSC2007]数据备份Backup 题意: 给定一个长度为\(n\)的数组,要求选\(k\)个数且两两不相邻,问最小值是多少 题解: 做一个小根堆,把所有值放进去,当选择一个值 ...
- 【bzoj1150】[CTSC2007]数据备份Backup 模拟费用流+链表+堆
题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家中尽享计算机游戏 ...
随机推荐
- Puppeteer学习笔记 (2)- Puppeteer的安装
本文链接:https://www.cnblogs.com/hchengmx/p/11009849.html 1. node的下载安装 由于puppeteer是nodejs的一个库,所以首先需要安装no ...
- Ribbon的ServerStats引起内存泄露问题总结
问题描述 服务运行一段时间之后,出现页面卡顿加载慢的问题,使用top命令查看了服务器的使用情况,发现CPU飙高,接着查看了该进程中每个线程的占用情况,发现导致CPU高的线程是JVM垃圾回收的线程,然后 ...
- Linux常用操作:文件及文件夹
一.创建 (1)mkdir 创建一个目录 (2)touch 创建一个空文件 注:-r 表示递归操作 二.删除 rm 删除文件 rm -r 删除目录 rm -r * 删除目录下的所有文件 注:-f 不用 ...
- 这就是艺术「GitHub 热点速览 v.22.25」
作者:HelloGitHub-小鱼干 不知道写了那么久代码的你,是否还记得"代码写诗"这个词,它是用来形容代码的优雅.但是本周的项目,虽然你看到的是代码的成品,也会惊讶于它的艺术感 ...
- 名校AI课推荐 | UC Berkeley《人工智能导论》
深度学习具备强感知能力但缺乏一定的决策能力,强化学习具备决策能力但对感知问题束手无策,因此将两者结合起来可以达到优势互补的效果,为复杂系统的感知决策问题提供了解决思路. 今天我们推荐这样一门课程--U ...
- 如何通过WinDbg获取方法参数值
引入 我们在调试的过程中,经常会通过查看方法的输入与输出来确定这个方法是否异常.那么我们要怎么通过 WinDbg 来获取方法的参数值呢? WinDbg 中主要包含三种命令:标准命令.元命令(以 . 开 ...
- NC16597 [NOIP2011]聪明的质监员
NC16597 [NOIP2011]聪明的质监员 题目 题目描述 小T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 \(n\) 个矿石,从 \(1\) 到 \(n\) 逐一编号,每个矿 ...
- docker的平替--podman
前言 我们都知道,docker这个东西,是CaaS(Container as a Service,容器即服务)的通常解法.我们使用docker来管理容器的生命周期,比如镜像的生成.容器的管理和定制(D ...
- scrapy框架入门
scrapy迄今为止依然是世界上最好用,最稳定的爬虫框架,相比于其他直接由函数定义的程序, scrapy使用了面向对象并对网页请求的过程分成了很多个模块和阶段,实现跨模块和包的使用,大大提升了代码的稳 ...
- Vue3 项目实战
使用Vue3 开发一个小米商城 业务流程 登录---> 产品首页--->产品站--->产品详情 购物车--->订单确认--->订单支付--->订单列表 业务开发流程 ...