zoukankan      html  css  js  c++  java
  • 0x10基本数据结构(0x17 二叉堆)例题4:合并果子

    题意

    题目链接

    【题意】
    在一个果园里,达达已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。
    达达决定把所有的果子合成一堆。
    每一次合并,达达可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。
    可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。
    达达在合并果子时总共消耗的体力等于每次合并所耗体力之和。
    因为还要花大力气把这些果子搬回家,所以达达在合并果子时要尽可能地节省体力。
    假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使达达耗费的体力最少,并输出这个最小的体力耗费值。
    例如有3种果子,数目依次为1,2,9。
    可以先将1、2堆合并,新堆数目为3,耗费体力为3。
    接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。
    所以达达总共耗费体力=3+12=15。
    可以证明15为最小的体力耗费值。 
    
    
    【输入格式】
    输入包括两行,第一行是一个整数n,表示果子的种类数。
    第二行包含n个整数,用空格分隔,第i个整数ai是第i种果子的数目。 
    
    
    【输出格式】
    输出包括一行,这一行只包含一个整数,也就是最小的体力耗费值。
    输入数据保证这个值小于2^31。 
    
    
    【数据范围】
    1≤n≤10000,
    1≤ai≤20000 
    
    
    【输入样例】
    3 
    1 2 9 
    
    
    【输出样例】
    15 
    
    

    题解

    这道题目有个很明显的贪心思路就是每次取两个最小的数字,然后合并。

    为什么呢,现在有(a<=b<=c),那么((a+b+c+(a+b))-(b+c+a+b+c)<0),所以很明显先合并(a,b)更好,而选(a+c)一样比(a+b)大。

    那么我们维护一个小根堆,然后跑一下就行了。

    时间复杂度(O(nlogn))

    #include<cstdio>
    #include<cstring>
    #include<queue>
    using  namespace  std;
    priority_queue<int,vector<int>,greater<int> >a;
    int  n;
    int  main()
    {
        scanf("%d",&n);
        for(int  i=1;i<=n;i++)
        {
            int  x;scanf("%d",&x);
            a.push(x);
        }
        int  ans=0;
        for(int  i=1;i<n;i++)
        {
            int  x=a.top();a.pop();
            x+=a.top();a.pop();
            a.push(x);
            ans+=x;
        }
        printf("%d
    ",ans);
        return  0;
    }
    
    
  • 相关阅读:
    使用C++为对象分配与释放内存时的几个好习惯
    OGRE渲染流程
    【问题解决记录】无法识别的标志“-sdlMode”,在“p2”中
    四元数 Quaternion
    《The Cg Tutorial》阅读笔记——凹凸贴图 Bump Mapping
    尝试优化骨骼动画计算的意外收获——使用嵌入式汇编对float转int进行优化
    Model 的 Meta 选项
    dns资料
    ansible中的变量
    DockerFile与docker-compose.yml是什么
  • 原文地址:https://www.cnblogs.com/zhangjianjunab/p/11735139.html
Copyright © 2011-2022 走看看