BZOJ 1150 数据备份

news/2024/10/30 21:24:17/

https://cn.vjudge.net/problem/HYSBZ-1150

题目

你在一家 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≤100000)表示办公楼的数目,k(1≤k≤n/2)表示可利用的网络电缆的数目。 接下来的n行每行仅包含一个整数(0≤s≤1000000000),表示每个办公楼到大街起点处的距离。 这些整数将按照从小到大的顺序依次出现。

Output

输出应由一个正整数组成,给出将2K个相异的办公楼连成k对所需的网络电缆的最小总长度。

Sample Input

5 2 
1
3
4
6
12

Sample Output

4

题解

贪心,肯定选相邻的楼,于是计算出相邻的距离,转化为一堆数字中选出不相邻的K个数,使和最小

考虑如何选2个

1.先选最小的,再在剩余的不相邻的里面选次小的

2.不选最小的,选两个相邻的,如果选了一个不相邻的+其他,肯定不如选最小的+其他

 

为了反悔,可以选择以后将选了的最小的数变成$左边+右边-自己$,那么选变了以后的数就相当于选相邻的

 

由于要把堆和链表一起用,那么可以使用栈集合计算机编号的方法,在堆里面存数据的编号,链表直接使用编号,然后开一个编号转堆下标的数组

 

AC代码

#include<cstdio>
#include<cctype>
#include<algorithm>
#define REP(r,x,y) for(register int r=(x); r<(y); r++)
#define REPE(r,x,y) for(register int r=(x); r<=(y); r++)
#ifdef sahdsg
#define DBG(...) printf(__VA_ARGS__)
#else
#define DBG(...) void(0)
#endif
using namespace std;int _s; char _c;
template <class T>
void read(T&x) {x=0; do _c=getchar(); while(!isdigit(_c) && _c!='-'); _s=1; if(_c=='-') _s=-1, _c=getchar(); while(isdigit(_c)) { x=x*10+_c-'0'; _c=getchar();} x*=_s;
}#define MAXN 100007
#define MAXK 50007int dt[MAXN];
int hp[MAXN], sh;
int nxt[MAXN], prv[MAXN];
int th[MAXN];//, tl[MAXN];void up(int p) {while(p>1) {if(dt[hp[p]]<dt[hp[p>>1]]) {swap(th[hp[p]], th[hp[p>>1]]);swap(hp[p], hp[p>>1]);p>>=1;} else break;}
}void down(int p) {int s=p<<1;while(s<=sh) {if(s<sh && dt[hp[s+1]]<dt[hp[s]]) s++;if(dt[hp[s]]<dt[hp[p]]) {swap(th[hp[p]], th[hp[s]]);swap(hp[p], hp[s]);p=s; s<<=1;} else break;}
}void remove(int p) {hp[p]=hp[sh--]; th[hp[p]]=p; up(p); down(p);
}void lk(int a, int b) {nxt[a]=b; prv[b]=a;
}int main() {int n,k; read(n); read(k);int now,lst; read(lst);REP(i,1,n) {read(now); int t=now-lst; lst=now;dt[i]=t; hp[++sh]=i; th[i]=sh; nxt[i]=i+1, prv[i]=i-1; up(sh);}int ans=0;REP(c,0,k) {int x=hp[1];ans+=dt[x]; DBG("!%d\n", dt[x]);if(prv[x]==0 && nxt[x]==n) break;if(prv[x] && nxt[x]!=n) {int nd=dt[prv[x]]+dt[nxt[x]]-dt[x];remove(th[prv[x]]); remove(th[nxt[x]]); lk(prv[prv[x]],x); lk(x, nxt[nxt[x]]);remove(th[x]);dt[x]=nd; hp[++sh]=x; th[x]=sh; up(sh);} else if(prv[x]) {remove(th[prv[x]]); nxt[prv[prv[x]]]=n;remove(th[x]);} else {remove(th[nxt[x]]); prv[nxt[nxt[x]]]=0;remove(th[x]);}}printf("%d\n", ans);
}

 

转载于:https://www.cnblogs.com/sahdsg/p/11244471.html


http://www.ppmy.cn/news/325596.html

相关文章

【游戏程序设计】三维游戏示例-战术竞技游戏Demo(二)

突然相遇&#xff1a; 然后死掉. 源代码以及实现方法&#xff1a; 首先定义一个Character类为角色的基类&#xff0c;然后英雄魔兽(战士)类Warcraft与托尼(法师)类Timy继承于它。分别实现对应的方法。 角色类有许多的方法&#xff0c;也有一些需要子类实现的虚函数方法。 Ch…

用easyx图形库做一个简单的c++小游戏---障碍跑酷(还有难度等级)

用easyx图形库做一个简单的c小游戏—障碍跑酷 开发环境&#xff1a;visual c6.0 库&#xff1a;easyx图形库 下载地址>>> (https://easyx.cn/downloads/) 当时我原本是想模仿做一个Flappy Bird的小游戏&#xff0c;在想如何写的时候突然有了新的想法&#xff0c;就有…

python设计拼图游戏tkinter_tkinter做一个拼图游戏

今天我们利用canvas绘制、删除图片的的函数&#xff0c;以及鼠标事件的绑定来制作一个简单的九宫格拼图游戏。 首先从网上下九张图&#xff0c;它们是把一张图分割成了九宫图&#xff0c;打乱后显示在canvas画布上。 接下来我们只要实现图片的选中与拖动即可&#xff0c;用到了…

c语言跑酷游戏,C++用easyx图形库实现障碍跑酷小游戏

用easyx图形库做一个简单的c++小游戏—障碍跑酷 开发环境:visual c++6.0 库:easyx图形库 下载地址 当时我原本是想模仿做一个Flappy Bird的小游戏,在想如何写的时候突然有了新的想法,就有了这个障碍跑酷的小游戏。(这是我之前写的代码,没有很注重规范,看上去有点乱,但我…

C++基础学习(1)

C基础学习 一、C的引用知识点1.1 c中的引用1.2 引用做函数参数1.3 引用做函数的返回值1.4 引用的本质1.5 常量引用 二、函数进阶2.1 函数的默认参数2.2 函数占位参数2.3 函数重载 三、面向对象3.1 封装3.1.1 封装的意义 3.2 封装的访问权限3.3 struct和class区别3.4 构造函数与…

【大学计算机技术】第一章 测试15

文章目录 选择题 选择题 计算机操作系统是( )。 A. 一种使计算机便于操作的硬件设备 B. 计算机的操作规范 C. 计算机系统中必不可少的系统软件 D. 对源程序进行编辑和编译的软件 正确答案&#xff1a; C 计算机操作系统的主要功能是( )。 A. 对源程序进行翻译 B. 对计算机的所…

C226 进入定影单元 提示更新

由于定影单元提示要更新&#xff0c;但是打印出来的影像正常所以需要设置一下 1、进入维修模式 菜单-计数器显示小键盘-停止-0-0-停止-0-1 维修模式密码&#xff1a;输入四组9272 2、计数器 ->寿命 -> 新品发布 然后选中感光鼓&#xff0c;接下来是最为重要的一…

Win10 安装美能达打印机驱动程序失败, 怎么也安装不了

环境&#xff1a; Win10 专业版 柯尼卡美能达-bizhub287 问题描述&#xff1a; 安装打印程序失败&#xff0c;重启计算机和在安全模式下测试都不能安装 解决方案&#xff1a; 1.正常进入系统 2.按住“shift”键不放&#xff0c;点开始菜单选择“重启” 3.选“疑难解答”…