合并果子
2017-07-28 13:38
134 查看
经典二叉堆——合并果子
萌新第一次写博客233,为了记录一下这道经典的题的二叉堆做法。(以后再忘记就尴尬了233)。原题:合并果子
1.基本二叉堆的建立:
–建立一个小根堆
void binary_heap(int x) { while(x/2>=1) { int j=x/2; if(a[j]>a[x]) { swap(a[j],a[x]); x=j; } *else { break; }* } }
2.进行删除与调整操作(a[1])
–每次将新的元素放置在A【1】时,将它调整至合适的位置
void rise(int y) { while(y*2<=tot)//由于合并果子是每次将两个果子合并为一个,所以每次都会少一个“儿子”,这时候就需要将总数进行调整 { (开始时int tot=n;每次进行删除调整时tot--) int k=y*2; if(y*2+1<=tot&&a[y*2+1]<a[y*2}) k++; if(a[k]<a[y]) swap(a[k],a[y]); *else break;* } }
3.合并果子的调整操作
由于要消耗体力最小,所以每次合并之后将新的果子找到自己的位置,使其一直保持为小根堆的形态。合并时,先使ex+=a1,然后舍弃掉a1.之后紧接着进行一次小根堆的调整。这时再使ex+=a[1],a[1]=ex,然后rise(1).重复操作n次,结果就是最小的值。
4.代码如下
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; int n; int ex; int a[11000]; int ans=0; int tot; int vis[11000]; int swapp; void binary_heap(int x) { while(x/2>=1) { int j=x/2; if(a[j]>a[x]) { swapp=a[j]; a[j]=a[x]; a[x]=swapp; x=j; } else { break; } } } void rise(int y) { while(y*2<=tot) { int k=y*2; if(y*2+1<=tot&&a[y*2+1]<a[y*2]) { k++; } if(a[y]>a[k]) { swapp=a[y]; a[y]=a[k]; a[k]=swapp; y=k; } else break; } } int main() { cin>>n; tot=n; for(int i=1;i<=n;i++) { cin>>a[i]; binary_heap(i); } for(int i=1;i<n;i++) { ex=0; ans+=a[1]; ex+=a[1]; a[1]=a[tot]; tot--; rise(1); ans+=a[1]; ex+=a[1]; a[1]=ex; rise(1); } cout<<ans; return 0; }
//////
相关文章推荐
- 合并果子(优先队列 +或者+哈夫曼)
- 树-堆结构练习——合并果子之哈夫曼树
- AHOI1997彩旗飘飘 VIJOS1097合并果子(noip2007)
- 树-堆结构练习——合并果子之哈夫曼树(优先队列)
- 合并果子
- 树-堆结构练习——合并果子之哈夫曼树 (STL 优先队列)
- 合并果子,浅谈堆
- NOIP2004 合并果子
- P1097合并果子解题报告
- 【NOIP合并果子】uva 10954 add all【贪心】——yhx
- NOIP2004Day1P2合并果子
- 合并果子
- 单调队列及其deque写法 HDU 3415+Poj 4002 (日期处理) + 合并果子
- codevs1063 合并果子 优先队列(小根堆)
- 【堆排】合并果子
- 树-堆结构练习——合并果子之哈夫曼树
- NOIP2004合并果子
- codevs 1063 合并果子 STL 优先队列
- 1063 合并果子 优先队列
- NOIP提高组2004 合并果子题解