题面

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 (贪心)的更多相关文章

  1. BZOJ1150 [CTSC2007] 数据备份Backup 贪心_堆_神题

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

  2. BZOJ1150 [CTSC2007]数据备份Backup 贪心 堆

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1150 题意概括 数轴上面有一堆数字. 取出两个数字的代价是他们的距离. 现在要取出k对数,(一个数 ...

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

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

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

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

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

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

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

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

  7. 【BZOJ1150】[CTSC2007]数据备份Backup 双向链表+堆(模拟费用流)

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

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

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

  9. 【bzoj1150】[CTSC2007]数据备份Backup 模拟费用流+链表+堆

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

随机推荐

  1. Linux免密登陆配置(互信配置)

    Linux免密登陆配置(互信配置) 1.生成当前用户的秘钥文件 [oracle@localhost .ssh]$ ssh-keygen -t rsa 2.配置远程登录用户的公钥文件 将公钥文件拷贝至另 ...

  2. 给王心凌打Call的,原来是神奇的智能湖仓

    图文原创:谭婧(王凌老粉) "爷青回" "我们只是老了,并没有死." 谭老师作为老粉,热烈庆祝"甜心教主"王凌成为现象级翻红顶流. 只要地球 ...

  3. 关于android里activity之间利用button组件使用intent跳转页面

    在需要跳转的activity 中 添加 Button button = findViewById(R.id.login);button.setOnClickListener(new View.OnCl ...

  4. Linux文件的特殊属性

    文件的特殊属性 作用:文件的权限不能显示root用户,为了防止root用户的误操作,所以需要特殊属性来防止root用户的误操作. chattr工具: 可以给文件添加特殊的属性 +i:对这个文件不能修改 ...

  5. Nginx开机自启

    编写service脚本: vim /usr/lib/systemd/system/nginx.service 将以下内容复制到nginx.service文件中 ps:我的nginx目录是/usr/lo ...

  6. NC20032 [HNOI2003]激光炸弹

    NC20032 [HNOI2003]激光炸弹 题目 题目描述 一种新型的激光炸弹,可以摧毁一个边长为R的正方形内的所有的目标. 现在地图上有 \(n\) (\(N ≤ 10000\))个目标,用整数 ...

  7. 013(oulipo)

    题目:http://ybt.ssoier.cn:8088/problem_show.php?pid=1455 题目描述:在母串里找子串出现的次数 题目思路:与字符串的搜索有关那就立刻找到哈希 从s[1 ...

  8. springboot配置logback.xml

    由于springboot框架自带log4j,因此我们只需配置下logback文件,即可, 在main/resources根目录下,新建logback-spring.xml文件,copy下述代码: &l ...

  9. VIM学习笔记-1

    VIM vim主要分为3个模式: Normal 模式 Insert模式 command模式 Insert 模式就是普通的编辑模式,没有太多可以介绍的,vim的主要功能都在 Normal 模式和 Com ...

  10. VGA设计(原理说明。Verilog代码实现,仿真结果)

    各类显示屏的显示原理大部分是利用人眼的视觉暂留效应.比如之前的数码管显示就是设计每个周期内各个小段按顺序显示,来达到显示一个数字的效果. VGA同理,显示屏在显示时是一个像素一个像素地显示,在人眼看来 ...