P1090 [NOIP 2004 提高组] 合并果子

题目理解

P1090 [NOIP 2004 提高组] 合并果子 是一道经典的 贪心算法 题目,要求将若干堆果子合并成一堆,每次合并消耗的体力等于两堆果子的重量之和,目标是找到 最小的总体力消耗。

解题思路

  1. 贪心策略

    • 每次选择 当前最小的两堆果子 合并,可以保证每次合并的体力消耗最小,从而使得总体力消耗最小。

  2. 优先队列(小根堆)优化

    • 使用优先队列(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;
}

 

posted @ 2025-05-30 15:42  CRt0729  阅读(89)  评论(0)    收藏  举报