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

其实说白了,这个题目的题意就是说,对于一组数进行差分,找出k个数两两不相邻使选取的数最少
首先有一种很容易想到的nk的算法,就是进行DP,不过在这里需要滚动,因为内存不够,用f[i,j]表示到第i个点的时候选了j个,这个转移比较简单,就不再多说了
下面我们来看正解,这个题目的做法很多,这里讲一下贪心的做法。
首先,直接贪心肯定是不对的,比如4,3,5,10,贪心的结果是13,但是显然结果应该是9,所以这里的贪心就是带反悔的(这种思想有点像网络流,所以有大佬说这个是模拟费用流,但是我不会emmm)。
怎么反悔呢?
每去除来一个点i,我们就要把i和两边的点给删去,和ans+s[i]相反的就是ans+s[i-1]+s[i+1],所以,我们需要的是在删去i之后加上一个值为s[i-1]+s[i+1]-s[i]的点,这样的话,如果取了两边点,两次加起来就是s[i-1]+s[i+1]-s[i]+s[i]=s[i-1]+s[i+1],相当于取了两边的点。
对于这个的维护,可以用堆,可以用平衡树(其实我觉得用平衡树好维护一些,但是懒得慌,就打了优先队列)

AC代码如下:

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
#define re register
#define gc getchar()
#define ll long long
#define il inline
const int N=,lim=(<<);
const ll INF=1e9;
il int read() {
re int x(),f();
re char ch=gc;
while(ch<''||ch>'') {
if(ch=='-') f=-;
ch=gc;
}
while(ch>=''&&ch<='') {
x=(x<<)+(x<<)+(ch^);
ch=gc;
}
return x*f;
}
struct node {
long long x,id;
bool operator < (const node & a) const {
return x>a.x;
}
};
priority_queue <node> q;
int n,k,s[N],la[N],ne[N];
bool vis[N];
int main() {
n=read(),k=read();
for(int i=; i<=n; ++i)
s[i]=read();
for(int i=; i<n; ++i) {
s[i]=s[i+]-s[i];la[i]=i-,ne[i]=i+;
q.push((node){
s[i],i
});
}
s[n]=s[]=INF;
int num=;
long long ans=;
for(re int i=; i<=k; ++i) {
node a;
while(vis[q.top().id]&&!q.empty())
q.pop();
a=q.top(),q.pop();
ans+=a.x;
int l=la[a.id],r=ne[a.id];
s[a.id]=s[l]+s[r]-s[a.id];
ne[la[l]]=ne[l],la[ne[l]]=la[l],la[l]=ne[l]=;
ne[la[r]]=ne[r],la[ne[r]]=la[r],la[r]=ne[r]=;
vis[l]=vis[r]=;
q.push((node) {
s[a.id],a.id
});
}
cout<<ans;
return ;
}

题解:[APIO/CTSC 2007]数据备份的更多相关文章

  1. 洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心)

    洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/132 ...

  2. P3620 [APIO/CTSC 2007]数据备份

    P3620 [APIO/CTSC 2007]数据备份 题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同 ...

  3. 洛谷 P3620 [APIO/CTSC 2007]数据备份 解题报告

    P3620 [APIO/CTSC 2007]数据备份 题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同 ...

  4. [luogu3620][APIO/CTSC 2007]数据备份【贪心+堆+链表】

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

  5. [APIO/CTSC 2007]数据备份(贪心+堆)

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

  6. 洛谷P3620 [APIO/CTSC 2007] 数据备份 [堆,贪心,差分]

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

  7. P3620 [APIO/CTSC 2007]数据备份[优先队列+贪心]

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

  8. 题解 P3620 【[APIO/CTSC 2007]数据备份】

    直接贪心(每次选最小)的话显然不对...样例都过不了... 选两个办公楼的时候,显然不能跨越另一个楼,这样不优... 于是 先把原数列处理成n-1个的数(每一个办公楼和上一个的距离),存在a[]中 题 ...

  9. [APIO/CTSC 2007]数据备份

    嘟嘟嘟 这竟然是一道贪心题,然而我在不看题解之前一直以为是dp. 首先最优的配对一定是相邻两个建筑物配对,所以我们求出差分数组,就变成了在n - 1个数中选出不相邻的k个数,使这k个数的和最小. 贪心 ...

随机推荐

  1. SpringBoot Web学习笔记

    一.资源的访问: 情形一.所有的  /webjars/**  都会去 classpath:/META_INFO/resource/webjars/ 下找资源: webjars:以jar包的方式引入静态 ...

  2. 腾讯云服务器 ubuntu 设置允许root用户登录

    背景:最近购买了腾讯云服务器,使用了Ubuntu Server 14.04.1 LTS 64位操作系统,腾讯云主机ubuntu系统默认用户名为ubuntu,登录服务器时每一次都是以默认账号ubuntu ...

  3. 算法:数组中和为s的两个数字

    @问题 :题目描述输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们如果有多对数字的和等于S,输出两个数的乘积最小的. 输出描述:对应每个测试案例,输出两个数,小的先输出.@思路: 两个 ...

  4. javaweb学习--jsp

    阅读电子书<Java Web从入门到精通>密码:461c,学习JavaWeb基础知识.由于本人已有html基础,所以直接略过前面部分,进入jsp学习 jsp页面添加库引用,引入项目文件 引 ...

  5. Lcd(一)显示原理

    一.LCD控制原理 S5PV210处理器中自带LCD控制器,控制LCD的显示,把 LCD 图像数据从一个位于系统内存的 video buffer 传送到一个外部的 LCD 驱动器接口. 类型: STN ...

  6. 炫龙炎魔T1笔记本 Win7 系统安装

    系统链接:https://pan.baidu.com/s/1T5FdJf1jhTj78vEBYCXxyA 密码:rl7m 1.制作系统盘(下载文件中有教程),插好U盘,重启计算机 2.按F2进入BOS ...

  7. windows下php7.1安装redis扩展以及redis测试使用全过程

    最近做项目,需要用到redis相关知识.在Linux下,redis扩展安装起来很容易,但windows下还是会出问题的.因此,特此记下自己实践安装的整个过程,以方便后来人. 一,php中redis扩展 ...

  8. 记录Vim常用命令

    命令 简单说明 i 进入编辑模式,光标在原位置 I 进入编辑模式,光标在行首位置 o 从光标所在行,下面一行开始编辑 O 从光标所在行,上面一行开始编辑 a 从光标当前字符后编辑 A 从光标所在行的行 ...

  9. 如何用Nginx解决前端跨域问题?

    前言 在开发静态页面时,类似Vue的应用,我们常会调用一些接口,这些接口极可能是跨域,然后浏览器就会报cross-origin问题不给调. 最简单的解决方法,就是把浏览器设为忽略安全问题,设置--di ...

  10. ThreadPoolExecutor解析

    前言:在最新的阿里规范中强制使用ThreadPoolExecutor方式创建线程池,不允许使用Executors,因此有必要对ThreadPoolExecutor进行进一步了解. 1.ThreadPo ...