中矿大新生赛 G 甄总搬石头【优先队列/哈夫曼/贪心】

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

https://www.nowcoder.com/acm/contest/41/G

现在草地上有n堆石头,甄总想要合并这n堆石头成为1堆,但是他每次能力有限,所以只能一次合并2堆石头至1堆。
现在已知第i堆石头有ai块,假设甄总要合并第i堆和第j堆石头,则需要花费ai+aj的力气。
给出n堆石头每堆石头的个数,求出甄总要合并n堆成1堆石头一共需要多少力气。

输入描述:

第1行输入一个整数n,代表一共有n堆石头。
第2行输入n个整数ai,表示第i堆有ai块石头。

输出描述:

输出一行整数,表示一共需要多少力气。
示例1

输入

3
1 2 3

输出

9

【分析】:又是一道披着DP-石子归并外衣,仔细读题发现不是DP的题目!和codeforces A.分披萨一样的!因为不是相邻。

     //经典贪心问题,用堆维护力气中的最小值,每次从堆中取出最小的两个,计算总和并将总和放回堆中,累加得出结果。(合并果子问题)

【代码】:
#include <bits/stdc++.h>
using namespace std;
const int maxn =1e5+10;
#define LL long long
LL a[maxn];
priority_queue <int,vector<int>,greater<int> > q;
int n,x,sum=0;
int main()
{
    int a,b;
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>x;
        q.push(x);
    }
    while(q.size()!=1)
    {
        a=q.top();
        q.pop();

        b=q.top();
        q.pop();

        q.push(a+b);

        sum+=a+b;
    }
    cout<<sum<<endl;
    return 0;
}
STL
原文地址:https://www.cnblogs.com/Roni-i/p/7906433.html