堆:合并果子

传送门

题意:在一个果园里,达达已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。达达决定把所有的果子合成一堆。
每一次合并,达达可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。例如有3种果子,数目依次为1,2,9。
可以先将1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。
所以达达总共耗费体力=3+12=15。
可以证明15为最小的体力耗费值。

数据范围
1≤n≤10000,
1≤ai≤20000

输入样例:
3
1 2 9

输出样例:
15

思路

  • 显然这个题求消耗最小值,便可以用优先队列来实现(stl里的队列其实就是用堆来实现的)
  • 每次从队列中取两堆最小的果子来合并(优先队列是升序排列的),把合并后的果子再放回队列,如此便能得到答案。

代码实现:

#include 
#include 
#include 
#include 
using namespace std;

int main()
{
    int n;
    cin >> n;
    priority_queue<int, vector<int>, greater<int>> que;

    while (n -- ){
        int v;
        cin >> v;
        que.push(v);
    }
    
    int res = 0;
    while (que.size() > 1)
    {
        int x = que.top();
        que.pop();
        int y = que.top();
        que.pop();
        res += x + y;
        que.push(x + y);
    }
    cout << res << endl;
    return 0;
}

你可能感兴趣的:(数据结构)