题面

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. Sublime text eslint windows 配置

    1. 下载安装eslint npm install -g eslint 2. 设置环境变量 C:\Users\<你的用户名>\AppData\Roaming\npm 3. sublime ...

  2. CVE-2022-30190 Follina Office RCE分析【附自定义word钓鱼模板POC】

    昨天看了下'Follina' MS-MSDT n-day Microsoft Office RCE 这个漏洞,修改了下chvancooten的脚本,实现可以自定义word模板,便于实战中钓鱼使用,自己 ...

  3. 文件上传漏洞靶场分析 UPLOAD_LABS

    文件上传漏洞靶场(作者前言) 文件上传漏洞 产生原理 PASS 1) function checkFile() { var file = document.getElementsByName('upl ...

  4. 关于vue cli 使用iview 自定义主题遇到的坑

    定制主题,这里讲变量覆盖 当你老老实实的把上面文档中的代码一一复制粘贴到项目文件中时,发现了还没装less,所以你就 npm install less –savenpm install less-lo ...

  5. UiPath存在文本Text Exists的介绍和使用

    一.Text Exists的介绍 检查是否在给定的UI元素中找到了文本,输出的是一个布尔值 二.Text Exists在UiPath中的使用 1. 打开设计器,在设计库中新建一个Sequence,为序 ...

  6. java基础知识点梳理

    前言 在别人追问我以下几个问题,自己在问题回答上不够全面和准确,对此自己把专门针对这几个问题进行总结! java相关问题 1.Java中构造方法跟普通方法的区别? 构造方法与普通方法的调用时机不同. ...

  7. JQuery select与radio的取值与赋值

    radio 取:$("input[name='NAME']:checked").val(); 赋:$("input[name='NAME'][value='指定值']&q ...

  8. React技巧之导入组件

    正文从这开始~ 总览 在React中,从其他文件中导入组件: 从A文件中导出组件.比如说,export function Button() {} . 在B文件中导入组件.比如说,import {But ...

  9. Pod控制器类型

    Pod是kubernetes的最小管理单元,在kubernetes中,按照pod的创建方式可以将其分为两类: - 自主式pod:kubernetes直接创建出来的Pod,这种pod删除后就没有了,也不 ...

  10. 史上最全学习率调整策略lr_scheduler

    学习率是深度学习训练中至关重要的参数,很多时候一个合适的学习率才能发挥出模型的较大潜力.所以学习率调整策略同样至关重要,这篇博客介绍一下Pytorch中常见的学习率调整方法. import torch ...