【C++】两个和尚抬水吃/搬水果(贪心)

题目描述

在一个寺庙里老和尚要求弟子给厨房抬水,假定所有的水已经分好装在不同大小的桶里,现要求最终把所有的水装到一个大桶中:小和尚很懒,无论桶里有多少水,总要二人抬;但是,小和尚也很聪明,每一次总是可以找到合适的二桶水,把其中一只倒进另—只桶里,他们消耗的体力等于二个水桶的重量之和。
你的任务是帮助二个小和尚设计出合装的次序方案,使得耗费的体力最少,并输出这个最小的体力耗费值。

输入输出形式

输入

第—行是—个整数n (1 <= n <= 30000),表示装有水的水桶的个数。
第二行包含n个整数,用空格分隔,第i个整数ai (1 <= ai <= 20000)是第i个水桶中水的重量。

输出

输出文件包括—行,一个整数,最小的体力耗费值。输入数据保证这个值小于231。

输入输出样例

样例输入1
3
1 2 9

样例输出1
15

样例输入2
10
3 5 1 7 6 4 2 5 4 1

样例输出2
120

思路 

贪心思想,每次将最小的两堆果子合并,直到最后只剩一堆果子
【正确性证明】:果子的合并可以看成树节点的合并如下图

代码

#include <bits/stdc++.h>
#include <vector>
#include <map>
#include <stack>
#define ll long long 
using namespace std;
const int N = 110; 

int main()
{
    int n,x;
    while(~scanf("%d",&n)&&n) {
        priority_queue<int,vector<int>,greater<int> >ansa;
        for(int i=1; i<=n; ++i)  { cin >> x;  ansa.push(x); }
        int ans=0;
        while(ansa.size()>1) {
            int a = ansa.top();  ansa.pop();
            int b = ansa.top();  ansa.pop();
            ans += (a+b);  ansa.push(a+b);
        }
        cout << ans << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Luoxiaobaia/article/details/124713472