测评会员优惠活动进行中 · 开通 VIP,有效期内测评不限次 VIP 优惠中 · 测评不限次 立即查看

A18787. 简易石子合并

填空题 较难

题目描述

简易石子合并

题目描述

给定n堆石子,每次合并任意两堆,合并代价为两堆石子重量之和,求将所有石子合并为一堆的最小总代价。

输入格式

第一行整数n;第二行n个整数表示每堆石子重量。

输出格式

输出最小总代价。

数据范围 1≤n≤100

参考答案

#include <iostream> #include <queue> using namespace std; int main() { // 小根堆定义,动态取出最小值 priority_queue<int, vector<int>, greater<int>> heap; int n, x; cin >> n; for(int i = 0; i < n; i++) { cin >> x; heap.push(x); } long long total = 0; // 防止数据溢出,必须用long long while(heap.size() > 1) { int a = heap.top(); heap.pop(); // 取最小第一堆 int b = heap.top(); heap.pop(); // 取最小第二堆 int sum = a + b; total += sum; // 累加合并代价 heap.push(sum); // 新堆入队 } cout << total; return 0; }

答案解析

1. 算法类型:优先队列(小根堆)贪心,哈夫曼树经典应用;

2. 贪心规则:每次取出重量最小的两堆合并,累加代价,新堆重新入堆;

3. 关键细节:总代价要用long long,防止整数溢出;必须用小根堆,大根堆答案完全错误;

4. 终止条件:堆中仅剩1堆时停止合并。

评分细则

正确定义小根堆(4分,大根堆直接0分)、循环合并逻辑正确(3分)、long long防溢出(2分)、输入输出正确(1分)

上一题 下一题