• 堆排序 P1090 合并果子


    P1090 合并果子

            本题要用到堆

           一个小根堆

           每次取出两堆,合并成一堆,为了让多多花费体力最少,我们要尽量少的重复大堆的合并,因此每次合并完以后,要把新的一坨放到堆里排一排,维护一个堆

    有必要强调一下这个合并的操作:

    (1)取出最小的一个(或一坨)果子 x

    (2)再取出最小的一个(或一坨)果子 y

    (3)合并为一坨 x+y 

    (4)体力值自然要加上 x+y 了

    (5)把 x+y 放到堆里维护一下这个堆,保证下次从堆中取出小的一个或一坨

    【代码】:

    #include<bits/stdc++.h>
    
    using namespace std;
    
    int n,guo,heap_size,ans=0,ans1=0,x,y;
    int heap[10001];
    
    void put(int d)     //小根堆入堆
    {
        int now,next;
        heap[++heap_size]=d;
        now=heap_size;
        while(now>1)
        {
            next=now>>1;
            if(heap[now]>=heap[next]) break;
            else swap(heap[now],heap[next]);
            now=next;
        }
    }
    
    int get() //小根堆出堆 { int now,next,res; res=heap[1]; heap[1]=heap[heap_size--]; now=1; while(now*2<=heap_size) { next=now*2; if(next<heap_size&&heap[next+1]<heap[next]) next++; if(heap[now]>heap[next]) swap(heap[now],heap[next]); now=next; } return res; }

    int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&guo); put(guo); } for(int i=1;i<n ;i++) //每次把两堆果子合为一堆,一共需要合并n-1次 { x=get(); //取出一堆小果子 y=get(); //再取出一堆小果子 ans+=x+y; //体力等于搬运这两个之和 put(x+y); //把这两个放进堆 } cout<<ans; return 0; }
  • 相关阅读:
    C#读取资源文件的两种方法及保存资源文件到本地
    T4模板编辑器
    VS (Visual Studio) 快捷键
    以太网帧类型速查
    线程间操作无效: 从不是创建控件“XXX”的线程访问它
    C# 集合
    C#控件之ListView
    C# Color颜色对照表
    Java的内存需要划分成为5个部分:
    Java学习:数组的使用和注意事项
  • 原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/10776597.html
Copyright © 2020-2023  润新知