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

非常神的一道题.
据说是模拟费用流(你也可以说是贪心加堆)
考虑最朴素的贪心:将所有元素都塞进一个堆里,那完一个就给旁边的打上标记,以此反复迭代.
不过,不难证明这种方法是完全错误的.
原因很简单:这个方法不能反悔,即每一个决策都是永久性的。
我们希望由可以反悔的机会。
首先,我们可以得到一个结论:
假若 $arr[i]$ 为当前数列中最小值,那么,如果不选 $arr[i]$,则一定要选择 $arr[i-1]$ 与 $arr[i+1]$。
于是,在加入 $arr[i]$,将其累积到答案中,并标记 $arr[i-1]$ 与 $arr[i+1]$ 不能选后,我们再将 $i$ 覆盖为 $arr[i-1]+arr[i+1]-arr[i]$。
为什么这样处理呢?
$arr[i]+arr[i-1]+arr[i+1]-arr[i]$ = $arr[i+1]+arr[i-1]$。以此达到了一个不断决策并反悔的过程。
以后可以专门学习一下模拟费用流,应该会对该问题有一个更加深刻的认识。
Code:
#include<bits/stdc++.h>
#define setIO(s) freopen(s".in","r",stdin)
#define maxn 1000000
#define inf 100000000000
using namespace std;
struct Node{
long long key;
int id;
Node(long long a=0,int b=0):key(a),id(b){}
bool operator < ( Node c) const{
return key > c.key;
}
};
priority_queue<Node>Q;
int tag[maxn],suf[maxn],pre[maxn];
long long h[maxn],arr[maxn];
int main(){
// setIO("input");
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;++i) scanf("%lld",&arr[i]);
for(int i=1;i<=n;++i) { h[i]=(long long) arr[i]-arr[i-1], suf[i]=i+1,pre[i]=i-1; }
h[0]=inf, suf[n]=pre[2]=0;
for(int i=2;i<=n;++i) Q.push(Node(h[i],i));
long long ans = 0;
for(int i=1;i<=k;++i) {
while(tag[Q.top().id]) Q.pop();
Node u = Q.top();
ans += (long long) u.key;
int cur = u.id;
int l = pre[cur],r = suf[cur];
h[cur] = h[l]+h[r]-h[cur];
tag[l]=tag[r]=1;
h[l]=h[r]=inf;
pre[cur]=pre[l],suf[pre[cur]] = cur;
suf[cur]=suf[r],pre[suf[r]] = cur;
Q.pop();
Q.push(Node(h[cur],cur));
}
printf("%lld",ans);
return 0;
}
BZOJ1150 [CTSC2007] 数据备份Backup 贪心_堆_神题的更多相关文章
- BZOJ1150 [CTSC2007]数据备份Backup 链表+小根堆
BZOJ1150 [CTSC2007]数据备份Backup 题意: 给定一个长度为\(n\)的数组,要求选\(k\)个数且两两不相邻,问最小值是多少 题解: 做一个小根堆,把所有值放进去,当选择一个值 ...
- BZOJ1150 [CTSC2007]数据备份Backup 贪心 堆
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1150 题意概括 数轴上面有一堆数字. 取出两个数字的代价是他们的距离. 现在要取出k对数,(一个数 ...
- bzoj1150 [CTSC2007]数据备份Backup 双向链表+堆
[CTSC2007]数据备份Backup Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2727 Solved: 1099[Submit][Stat ...
- BZOJ1150 [CTSC2007]数据备份Backup 【堆 + 链表】
题目 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家中尽享计算机游戏的 ...
- BZOJ1150[CTSC2007]数据备份Backup——模拟费用流+堆+链表
题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家中尽享计算机游 ...
- bzoj1150: [CTSC2007]数据备份Backup
题目大意: 在n个点中,选出k对相邻的互不相同的点,使k段距离的总和最小. 贪心,双向链表. 首先,点之间的距离是动态的,所以要用堆来维护. 每次都选择最近的点.但因为其他情况,可能最终不会选择这 ...
- bzoj 1150: [CTSC2007]数据备份Backup【链表+堆】
参考:http://blog.csdn.net/Regina8023/article/details/44158947 神奇的做法.题意相当于若干个数取不相邻的k个使最小.先把数组差分,len表示这段 ...
- 【BZOJ1150】[CTSC2007]数据备份Backup 双向链表+堆(模拟费用流)
[BZOJ1150][CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此 ...
- 【BZOJ 1150】 1150: [CTSC2007]数据备份Backup (贪心+优先队列+双向链表)
1150: [CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设 ...
随机推荐
- 4.Thymeleaf的常用标签
一.常用标签 二.foreach案例 1.创建项目 2. 创建Student.java package cn.kgc.pojo; /** * Created by Administrator on 2 ...
- Firefox配置Fiddler
Fiddler: Toos->Telerik Fiddler Options->HTTPS->Capture HTTPS CONNECTs Toos->Telerik Fidd ...
- LCS,LIS,LCIS
网站:CSUST 8月3日(LCS,LIS,LCIS) LCS: 以下讲解来自:http://blog.csdn.net/yysdsyl/article/details/4226630 [问 ...
- MySQL主要命令(4)
显示数据, 给列区别名: select coL_name as 别名 from table_name;
- java.lang.Object 方法解析
1.clone() a.是一个native方法,效率比非native高 b.是protected 修饰的,要用他必须继承object,默认都是继承object的 c.返回是一个object 对象,需要 ...
- javascript推断浏览器类型
<script> window["MzBrowser"]={};(function() { if(MzBrowser.platform) return; var ua ...
- 【机房收费系统C#版】——导出Excel
前言 机房合作開始好长了一段时间.反重复复开了几次会,项目也是一拖再拖,作为组长.有80%的责任都在于我.为了不让这个项目陪着我过春节.要求自己一定要在这几天敲完. 还是一样的问题,用C#敲,从一開始 ...
- Keil5.15使用GCC编译器链接.a库文件
我们知道,当使用第三方的代码时,人家有可能会扔个Lib文件给你.这时候,别人仅仅要提供header文件给你,则你就能够通过Lib文件及header的函数声明,对Lib中的函数进行调用.在Keil中假设 ...
- cocos2dx 3.1从零学习(二)——菜单、场景切换、场景传值
回想一下上一篇的内容,我们已经学会了创建一个新的场景scene,加入sprite和label到层中.掌握了定时事件schedule. 我们能够顺利的写出打飞机的主场景框架. 上一篇的内容我练习了七个新 ...
- 扩展欧几里德 poj1061 青蛙的约会
扩展欧几里德很经典.可是也有时候挺难用的.一些东西一下子想不明确.. 于是来了一个逆天模板..仅仅要能列出Ax+By=C.就能解出x>=bound的一组解了~ LL exgcd(LL a, LL ...