浅谈堆:https://www.cnblogs.com/AKMer/p/10284629.html

题目传送门:https://lydsy.com/JudgeOnline/problem.php?id=1150

显然,这题用贪心转化一下题意就是给你\(n-1\)个数,选\(k\)个不相邻的数权值和最小。

假设最小值是\(a_x\),那么选完\(a_x\)之后\(a_{x-1}\)和\(a_{x+1}\)就不能选了。

如果\(a_{x-1}\)和\(a_{x+1}\)只选了某一个,显然把这个换成\(a_x\)更优。

所以最优解要么有\(a_x\)没有\(a_{x-1}\)和\(a_{x+1}\),要么同时有\(a_{x-1}\)和\(a_{x+1}\)。

所以我们每次从堆里取出来一个数之后,再把它前一个数和后一个数在堆里删掉,往堆里塞一个\(a_{i-1}+a_{i+1}-a_i\)即可。这样就可以考虑这两种情况了。

如果取出的这个数前面没有数或者后面没有数,那么就不需要加\(a_{i-1}+a{i+1}-a_i\)进堆,而是把它后一个数或者前一个数也从堆里删掉。可以证明,如果选了当前这个数,那么与它相邻的那个数必然不会被选。因为选与它相邻的数之后所遇到的局面,选当前数也能到达,这个决策包涵了选相邻的数的决策,而且选当前数更优,所以与当前数相邻的那个数可以直接舍弃了。

时间复杂度:\(O((n+k)logn)\)

空间复杂度:\(O(n)\)

代码如下:

#include <cstdio>
#include <algorithm>
using namespace std; const int maxn=1e5+5; int n,m,ans;
int a[maxn]; int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
} struct Linked_List {
int lst,nxt,val,in_heap; Linked_List() {} Linked_List(int _lst,int _nxt,int _val) {
lst=_lst,nxt=_nxt,val=_val;
}
}L[maxn]; struct Heap {
int tot;
int tree[maxn]; bool less(int id1,int id2) {return L[id1].val<L[id2].val;} void up(int pos) {
while(pos>1) {
if(less(tree[pos],tree[pos>>1])) {
swap(tree[pos],tree[pos>>1]);
swap(L[tree[pos]].in_heap,L[tree[pos>>1]].in_heap);
pos>>=1;
}
else break;
}
} void down(int pos) {
int son=pos<<1;
while(son<=tot) {
if(son<tot&&less(tree[son|1],tree[son]))son|=1;
if(less(tree[son],tree[pos])) {
swap(tree[son],tree[pos]);
swap(L[tree[son]].in_heap,L[tree[pos]].in_heap);
pos=son,son=pos<<1;
}
else break;
}
} void ins(int v) {tree[++tot]=v,L[v].in_heap=tot,up(tot);} int pop() {
int res=tree[1];
tree[1]=tree[tot--];
L[tree[1]].in_heap=1;
down(1);return res;
} void del(int id) {
if(id==tot) {tot--;return;}
tree[id]=tree[tot--];
L[tree[id]].in_heap=id;
if(id==1)down(id);
else if(id==tot)up(id);
else up(id),down(id);
}
}T; int main() {
n=read(),m=read();
for(int i=1;i<=n;i++) {
a[i]=read();
if(i>1) {
L[i-1]=Linked_List(i-2,i,a[i]-a[i-1]);
T.ins(i-1);
}
}
while(m--) {
int id=T.pop(),lst=L[id].lst,nxt=L[id].nxt;
ans+=L[id].val;
if(!lst) {
T.del(L[nxt].in_heap);
L[L[nxt].nxt].lst=0;continue;
}
if(nxt==n) {
T.del(L[lst].in_heap);
L[L[lst].lst].nxt=n;continue;
}
T.del(L[lst].in_heap),T.del(L[nxt].in_heap);
L[lst].val=L[lst].val+L[nxt].val-L[id].val;T.ins(lst);
L[lst].nxt=L[nxt].nxt,L[L[nxt].nxt].lst=lst;
}
printf("%d\n",ans);
return 0;
}

BZOJ1150:[CTSC2007]数据备份的更多相关文章

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

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

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

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

  3. BZOJ1150[CTSC2007]数据备份Backup——模拟费用流+堆+链表

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

  4. bzoj1150 [CTSC2007]数据备份

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

  5. BZOJ1150 [CTSC2007]数据备份Backup 【堆 + 链表】

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

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

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

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

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

  8. bzoj1150: [CTSC2007]数据备份Backup--贪心+优先队列维护堆

    题目大意:将k对点两两相连,求最小长度 易证得,最优方案中,相连的办公楼一定是取相邻的比取不相邻的要更优 然后就可以用贪心来做这道题了.. 之前向CZL大神学习了用堆来贪心的做法orz 大概思路就是将 ...

  9. bzoj1150: [CTSC2007]数据备份Backup

    题目大意: 在n个点中,选出k对相邻的互不相同的点,使k段距离的总和最小. 贪心,双向链表. 首先,点之间的距离是动态的,所以要用堆来维护.   每次都选择最近的点.但因为其他情况,可能最终不会选择这 ...

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

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

随机推荐

  1. Storm伪分布式搭建

    配置zookeeper 下载zookeeper tar包 解压:tar -zxvf zookeeper-3.4.10.tar.gz -C /root/training/ 配置 cd /root/tra ...

  2. Notepad++ Tidy2 插件的核心配置

    在已有配置的基础上加上这四行: 以免符号被转换成HTML实体了 preserve-entities: yes quote-ampersand: yes quote-marks: no quote-nb ...

  3. Android笔记之WebView加载网页的进度回调

    wv.setWebChromeClient(new WebChromeClient(){ @Override public void onProgressChanged(WebView view, i ...

  4. 我的Android进阶之旅------>Android关于Log的一个简单封装

    android.util.Log类,可以方便地用于在编码调试过程中打印日志.但是在发布后的产品中,如果有太多的日志打印,则会严重地影响性能.对android.util.Log类做一个简单的封装,当产品 ...

  5. python+NLTK 自然语言学习处理七:N-gram标注

    在上一章中介绍了用pos_tag进行词性标注.这一章将要介绍专门的标注器. 首先来看一元标注器,一元标注器利用一种简单的统计算法,对每个标识符分配最有可能的标记,建立一元标注器的技术称为训练. fro ...

  6. 说说JSON和JSONP,也许你会豁然开朗,含jQuery用例(转载)

     前言: 说到AJAX就会不可避免的面临两个问题,第一个是AJAX以何种格式来交换数据?第二个是跨域的需求如何解决?这两个问题目前都有不同的解决方案,比如数据可以用自定义字符串或者用XML来描述,跨域 ...

  7. 排序算法-python版

    总结了一下常见集中排序的算法 归并排序 归并排序也称合并排序,是分治法的典型应用.分治思想是将每个问题分解成个个小问题,将每个小问题解决,然后合并. 具体的归并排序就是,将一组无序数按n/2递归分解成 ...

  8. dojo 官方翻译 dojo/domReady 版本1.10

    官方地址:http://dojotoolkit.org/reference-guide/1.10/dojo/domReady.html#dojo-domready dom加载完成后,执行. requi ...

  9. 【leetcode刷题笔记】Spiral Matrix II

    Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. For ...

  10. jQuery横向手风琴

    在线演示 本地下载