合并果子(贪心+优先队列)

现在有n堆果子,第i堆有ai个果子。现在要把这些果子合并成一堆,每次合并的代价是两堆果子的总果子数。求合并所有果子的最小代价。

 

Input

第一行包含一个整数T(T<=50),表示数据组数。
每组数据第一行包含一个整数n(2<=n<=1000),表示果子的堆数。
第二行包含n个正整数ai(ai<=100),表示每堆果子的果子数。

 

Output

每组数据仅一行,表示最小合并代价。

 

Sample Input

2
4
1 2 3 4
5
3 5 2 1 4

Sample Output

19
33

分析:
贪心的思想
每次选择价值最小和次小的那两个进行合并,合并成新的果子放进果堆中,然后又在果堆中选择最小的和次小的进行合并
这样下来,合并所有果子所花费的代价肯定是最小的
所以我们可以用优先队列来实现这个过程
代价最小的果子优先

code:
#include<stdio.h>
#include <iostream>
#include <math.h>
#include <queue>
using namespace std;
int main()
{
    int t,n,a;
    scanf("%d",&t);
    while(t--)
    {
        priority_queue<int,vector<int>,greater<int> >q;//优先队列,数值小的优先
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a);
            q.push(a);
        }
        int ans=0,temp;
        while(q.size()>=2)//果堆中只有一个果子的时候合并就完成了
        {
            temp=0;
            temp+=q.top(),q.pop();
            temp+=q.top(),q.pop();//每次去优先队列队首的两个,因为他们是代价最小和次小的
            ans+=temp;
            q.push(temp);//将合并后的果子再次放入堆中
        }
        printf("%d\n",ans);
    }
    return 0;
}

 



posted @ 2018-07-31 16:33  西*风  阅读(919)  评论(0编辑  收藏  举报