题意
计算n个数的和,已知计算x,y两个数的和,需要花费(c*x+c*y)秒。
输出计算n个数字和的最小花费的时间。

方法一:
最小堆

思路:根据贪心思想,每次取出两个最小的数相加,并将两个最小的数之和push进队列。
        利用小根堆(优先队列),因为小根堆每次取出的都是最小值。

typedef long long ll;
class Solution {
public:
   
    long long solve(int n, int c, vector<int>& a) {
        priority_queue<int,vector<int>,greater<int>> q;//小根堆
        
        for(int i=0;i<n;i++){
            q.push(a[i]);
        }
        ll sum=0;
        while(q.size()>1){//当队列的大小>1时
            int x=q.top();//每次取出两个最小的数相加
            q.pop();
            int y=q.top();
            q.pop();
            q.push(x+y);//向队列push两个最小的数之和
            sum+=x+y;
        }
        return sum*c;
        
    }
};
时间复杂度:
空间复杂度:
方法二:
map查找
思路:map是红黑树实现,值是有序的(从小到大)。
            用map记录值为a[i]出现的次数。
            每次取出两个最小的数相加(即前两个数)相加。
typedef long long ll;

class Solution {
public:
   
    long long solve(int n, int c, vector<int>& a) {
        map<int,int> m;//有序红黑树
        for(int i=0;i<n;i++)//初始化,记录值为a[i]出现的次数
            m[a[i]]++;
        ll sum=0;
        for(int i=0;i<n-1;i++){
            int x=m.begin()->first,y;//寻找两个最小的数
            if(--m[x]==0){//如果m[x]==0,说明该值用完,删除掉该键
                m.erase(m.begin());
                y=m.begin()->first;
                if(--m[y]==0)
                    m.erase(m.begin());
            }else{
                y=x;
                if(--m[x]==0)//如果m[x]==0,说明该值用完,删除掉该键

                    m.erase(m.begin());
            }
            sum+=x+y;
            m[x+y]++;
        }
        return sum*c;
    }
};


时间复杂度:
空间复杂度: