APIO2007 数据备份 贪心+堆实现
来源:互联网 发布:淘宝改版中国质造 编辑:程序博客网 时间:2024/06/12 01:40
【算法分析】
n,k都有10^5,所以考虑贪心算法
最基本的贪心就是任意一对数必须是相邻的,这是显然的。
考虑到一重要结论:
假设现在有三条相邻的线段a1,a2,a3;a1>a2,a3>a2,如果a2小于等于最优解集中的最大元素,并且最优解集中不存在a2,则必同时存在a1,a3。
证明:如果最优解中只有a1或只有a3,那我可以把它换成a2,这组解仍然满足要求,但总距离更小。如果最优解中不存在a1或a3,那我可以用a2换掉解集中的最大元素。由于上述两种情况都不可能,所以题设成立。
但要注意,当线段在两端时就不满足了,因此,需要在两端加两个距离无穷大的哨兵。
利用这一点我们就可以构造一个增量算法:
每次选取一个最小的线段,然后把这条线段左右的两条线段合并在一起,新线段的权值为左右之和减去中间。
每一次操作之后,都会使解集中增加一条线段,而总费用增长了一个最小值。
【教训】
写del()函数的时候忘了将swap(pos[h[x]],pos[h[r]])写进去了。wa了很久
以后还是写一个change函数算了。
【代码】
#include <iostream>#include <cstring>#include <string>#include <cstdio>#include <algorithm>using namespace std;const int N=100005,INF=1<<30;int a[N],b[N],pos[N],L[N],R[N],h[N];int r;void up(int x){ int i=x,j; while (i>1) { j=i>>1; if (b[h[j]]>b[h[i]]) { swap(h[i],h[j]); swap(pos[h[i]],pos[h[j]]); i=j; } else break; }}void down(int x){ int i=x,j; while (i*2<=r) { j=i*2; if (j+1<=r && b[h[j]]>b[h[j+1]]) j++; if (b[h[i]]>b[h[j]]) { swap(h[i],h[j]); swap(pos[h[i]],pos[h[j]]); i=j; } else break; }}void ins(int i){ h[++r]=i; pos[i]=r; up(r);}void del(int x){ swap(h[x],h[r]); swap(pos[h[x]],pos[h[r]]); r--; up(x); down(x);}int main(){ int i,k,n,ans,l,r,mid; freopen("14.in","r",stdin); scanf("%d%d",&n,&k); for (i=1;i<=n;i++) scanf("%d",&a[i]); for (i=2;i<=n;i++) { b[i]=a[i]-a[i-1]; ins(i); } b[1]=b[n+1]=INF; ins(1);ins(n+1); for (i=1;i<=n+1;i++) L[i]=i-1,R[i]=i+1; ans=0; while (k--) { mid=h[1]; ans+=b[mid]; l=L[mid]; r=R[mid]; L[R[r]]=l; R[l]=R[r]; del(pos[mid]); del(pos[r]); b[l]=b[l]+b[r]-b[mid]; up(pos[l]); down(pos[l]); } printf("%d\n",ans);}
- APIO2007 数据备份 贪心+堆实现
- APIO2007 数据备份(贪心)
- 洛谷 3620 [APIO2007]数据备份 贪心
- BZOJ 1150 数据备份Backup 【贪心】【堆】
- [贪心+堆] BZOJ1150: [CTSC2007]数据备份Backup
- 【堆+贪心】BZOJ1150 [CTSC2007]数据备份Backup
- [bzoj1150][堆][贪心][CTSC2007]数据备份Backup
- APIO2007:风铃(Mobiles) 数据备份(Backup) 动物园(Zoo)
- BZOJ 1150 CTSC2007 数据备份Backup 堆+贪心
- 【BZOJ 1150】 [CTSC2007]数据备份Backup|链表|堆|贪心
- bzoj 1150: [CTSC2007]数据备份Backup 贪心&堆
- BZOJ 1150: [CTSC2007]数据备份Backup 堆,贪心
- 【贪心+堆+链表】BZOJ1150(CTSC2007)[数据备份Backup]题解
- [BZOJ]1150 1150: [CTSC2007]数据备份Backup 贪心 + 堆
- BZOJ1150(CTSC2007)[数据备份Backup]--贪心+链表+堆
- 【bzoj1150】【CSTC2007】【数据备份】【贪心】
- bzoj1150: [CTSC2007]数据备份Backup 贪心
- BZOJ 1150: [CTSC2007]数据备份Backup【贪心】
- Redis内存使用优化与存储
- 用VC++ MFC 修改外观和大小,图标、光标、背景
- html中的细线表格
- 指针与const之间的组合,写了个例子温习一下
- POJ 1751 Highways 最小生成树
- APIO2007 数据备份 贪心+堆实现
- ubuntu 备份还原
- UtilBox基础组件
- HDU-1698(线段树入门)
- java 远程调试butterfly
- Warning: The Copy Bundle Resources build phase contains this target's Info.plist file 'Info
- 多线程 NSThread
- java实现标点全角/半角转换
- 关于sfo的备注和bo的备注字段