bzoj1150: [CTSC2007]数据备份Backup
2016-03-06 15:50
363 查看
题目链接
bzoj1150题目描述
Description
Input
输入的第一行包含整数n和k,其中n(2 ≤ n ≤100 000)表示办公楼的数目,k(1≤ k≤ n/2)表示可利用的网络电缆的数目。接下来的n行每行仅包含一个整数(0≤ s ≤1000 000 000), 表示每个办公楼到大街起点处的距离。这些整数将按照从小到大的顺序依次出现。Output
输出应由一个正整数组成,给出将2K个相异的办公楼连成k对所需的网络电缆的最小总长度。Sample Input
5 21
3
4
6
12
Sample Output
4HINT
上面的样例输入给出了前面描述的示例情形 对于每一个测试点,如果写到输出文件中的答案正确,则得到该测试点100%的分数,否则得零分。30%的输入数据满足n≤20。60%的输入数据满足n≤10 000。题解
一道贪心好题。差分一下将问题转化为从n个数中选k个,任意两个不能相邻,使得k个数的和最小。如果每次都选最小的,将它相邻的删掉,这样贪心是有问题的。比方说100,2,1,2中选两个,我们会选1和100。而最优方案为两个2。为什么会有这种情况?当我们选了第x个数时,会对第x+1和x-1个数产生影响。有可能选x-1和x+1而不选x会更优(一定是x-1和x+1同时选)。我们可以这样调整。选了第x个数后将a[x-1]+a[x+1]-a[x]加入,并删除x,x-1,x+1。这样当我们选了这个数就意味着选第x+1,x-1个数而不选x。只有维护一个前驱后继,再用堆来做就行了。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<queue> #include<vector> using namespace std; #define mp make_pair #define N 100010 #define se second typedef pair<int,int>P; priority_queue<P> h; P tmp; int n,k,ans,a ,pre ,suc ; char BUF[200001],*buf,*end; #define getch() (buf==end?fread(BUF,1,200000,stdin),buf=BUF,end=buf+200000,*(buf++):*(buf++)) inline void read(int &x){ static char c; for(c=getch();c<'0'||c>'9';c=getch()); for(x=0;'0'<=c&&c<='9';c=getch())x=x*10+c-'0'; } int main(){ read(n); read(k); n--; for(int i=1;i<=n+1;i++) read(a[i]); for(int i=1;i<=n;i++) a[i]=a[i+1]-a[i]; for(int i=1;i<n;i++) pre[i]=i+1; for(int i=2;i<=n;i++) suc[i]=i-1; for(int i=1;i<=n;i++) h.push(mp(-a[i],i)); for(int i=1;i<=k;i++){ while(-h.top().first!=a[h.top().se]) h.pop(); tmp=h.top(); h.pop(); ans-=tmp.first; if(pre[tmp.se]&&suc[tmp.se]){ a[tmp.se]=a[pre[tmp.se]]+a[suc[tmp.se]]-a[tmp.se]; a[pre[tmp.se]]=a[suc[tmp.se]]=1000000007; pre[tmp.se]=pre[pre[tmp.se]]; suc[tmp.se]=suc[suc[tmp.se]]; suc[pre[tmp.se]]=pre[suc[tmp.se]]=tmp.se; h.push(mp(-a[tmp.se],tmp.se)); } else{ a[pre[tmp.se]]=a[suc[tmp.se]]=1000000007; pre[tmp.se]=pre[pre[tmp.se]]; suc[tmp.se]=suc[suc[tmp.se]]; suc[pre[tmp.se]]=pre[suc[tmp.se]]=0; } } printf("%d\n",ans); return 0; }
相关文章推荐
- Java 慎用方法级别的synchronized关键字
- 1051. Pop Sequence (25) 判断出栈序列是否合理
- iOS9 CGContextSaveGState错误
- SpringSecurity应用(二)
- 蓝桥杯2015省赛B组第1题
- 响应式设计(Responsive Design)之媒体查询
- Keras笔记 -- objective
- BestCoder Round #74 (div.2) A.LCP Array & B.Shortest Path
- Spring学习笔记--AOP和IOC、SSH整合
- SpringSecurity应用(一)
- Android 之Activity启动模式之 lauchMode
- c++基础总结一
- MySQL事物控制
- 1、今天,如何在html中加入音乐?
- 出差(十二)
- 【Java Web学习笔记】02-创建基于SpringMVC的web工程
- H3C交换机修改console密码
- UVA10057中位数的定义,个数
- Dynamic Programming
- 推送总结