NOIP 2004 提高组 P1090合并果子:从暴力枚举到优先队列的算法进化

一、问题本质分析
合并果子问题要求找到将所有果子堆合并为一堆的最小体力消耗值,本质上是一个构建最优二叉树的问题。每次合并消耗的体力等于两堆果子的重量之和。
二、C++优先队列解法
#include <iostream>
#include <queue>
using namespace std;
int main() {
int n, sum = 0;
cin >> n;
// 小顶堆优先队列
priority_queue<int, vector<int>, greater<int>> q;
for(int i = 0; i < n; ++i) {
int weight;
cin >> weight;
q.push(weight); // 初始化堆
}
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;
}三、算法核心思想
四、新手学习路径
五、常见误区警示
错误使用大顶堆导致结果偏大
未考虑整数溢出问题(本题数据范围无需处理)
忘记最后剩余单堆的特殊情况
原创内容 转载请注明出处
