• 合并果子(C++)[堆]


    题目:

    Description

    在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。

    多多决定把所有的果子合成一堆。

    每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。

    可以看出 所有的果子经过n-1次合并之后,就只剩下一堆了。

    多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。

    因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。

    假定每个果子重量都为1并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。

    例如有3种果子,数目依次为1,2,9。可以先将 1、2堆合并,新堆数目为3,耗费体力为3。

    接着,将新堆与原先的第三堆合并又得到新的堆,数目为12,耗费体力为 12。

    所以多多总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。

    Format

    Input

    包括两行,第一行是一个整数n(1 <= n <= 10000),表示果子的种类数。

    第二行包含n个整数,用空格分隔第i个整数ai(1 <= ai <= 20000)是第i种果子的数目。

    Output

    包括一行,这一行只包含一个整数,也就是最小的体力耗费值。

    输入数据保证这个值小于2^31。

    Samples

    输入数据 1

    1. 3
    2. 1 2 9

    输出数据 1

    15
    

    题解&Code

    1. #include
    2. using namespace std;
    3. int ans;
    4. int main()
    5. {
    6. int n,x;
    7. cin>>n;
    8. for(int i=1;i<=n;i++)
    9. {
    10. cin>>x;
    11. q.push(x);//将元素打入堆中
    12. }
    13. while(q.size()>=2)//堆的大小必须大于等于2
    14. {
    15. /*我们每次操作取出两个对顶元素(因为是小根堆,所以是堆中最小的两个元素)*/
    16. /*因为是最小的两个元素,所以合并价值是当前最小的*/
    17. /*且能保持全局价值最优*/
    18. int t1=q.top();
    19. q.pop();
    20. int t2=q.top();
    21. q.pop();
    22. /*将合并的果子打入堆中*/
    23. q.push(t1+t2);
    24. /*ans加上合并价值*/
    25. ans+=t1+t2;
    26. }
    27. cout<
    28. return 0;
    29. }

     

  • 相关阅读:
    第一天| 第一章 数组part01 数组理论基础、704. 二分查找、27. 移除元素
    LeetCode 0318. 最大单词长度乘积
    【Unity编辑器扩展】| SceneView面板扩展
    C++基础入门详解(二)
    【无标题】
    JavaScript|JavaScript 高级语法——详细汇总
    监控到底要哪些指标?
    Vue 中一些常用的指令和用法及其一些案例
    戴好这六顶帽子的项目经理,无论项目团队还是个人成长都受益终生
    Spring与Web环境集成
  • 原文地址:https://blog.csdn.net/ytk888/article/details/126289271