P1090 [NOIP 2004 提高组] 合并果子
题目理解
P1090 [NOIP 2004 提高组] 合并果子 是一道经典的 贪心算法 题目,要求将若干堆果子合并成一堆,每次合并消耗的体力等于两堆果子的重量之和,目标是找到 最小的总体力消耗。
解题思路
-
贪心策略
-
每次选择 当前最小的两堆果子 合并,可以保证每次合并的体力消耗最小,从而使得总体力消耗最小。
-
-
优先队列(小根堆)优化
-
使用优先队列(
priority_queue)动态维护当前所有果子堆的最小值,确保每次都能高效取出最小的两堆进行合并。
-
代码注释
#include<iostream> #include<algorithm> #include<queue> using namespace std; long long sum = 0; // 总体力消耗 priority_queue<int, vector<int>, greater<int>> q; // 小根堆(优先队列),保证每次取出的都是最小值 bool comp(int a, int b) { return a < b; // 比较函数(实际上优先队列的greater已经实现升序,此函数未使用) } int main() { int n; cin >> n; // 果子堆数 // 输入每堆果子的数量,并加入优先队列 for (int i = 1; i <= n; i++) { int x; cin >> x; q.push(x); // 所有果子堆按升序排列 } // 当堆数 >1 时,持续合并 while (q.size() != 1) { int a = q.top(); // 取出当前最小的堆 q.pop(); int b = q.top(); // 取出第二小的堆 q.pop(); sum += (a + b); // 累加本次合并的体力消耗 q.push(a + b); // 将合并后的新堆加入队列 } cout << sum << endl; // 输出最小总体力消耗 return 0; }

浙公网安备 33010602011771号