算法
(贪心,哈夫曼树,堆,优先队列) $O(nlogn)$
经典哈夫曼树的模型,每次合并重量最小的两堆果子即可。
时间复杂度
使用小根堆维护所有果子,每次弹出堆顶的两堆果子,并将其合并,合并之后将两堆重量之和再次插入小根堆中。
每次操作会将果子的堆数减一,一共操作 $n - 1$ 次即可将所有果子合并成1堆。每次操作涉及到2次堆的删除操作和1次堆的插入操作,计算量是 $O(logn)$。因此总时间复杂度是 $O(nlogn)$。
C++ 代码
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
int main()
{
int n;
scanf("%d", &n);
priority_queue<int, vector<int>, greater<int>> heap;
while (n -- )
{
int x;
scanf("%d", &x);
heap.push(x);
}
int res = 0;
while (heap.size() > 1)
{
int a = heap.top(); heap.pop();
int b = heap.top(); heap.pop();
res += a + b;
heap.push(a + b);
}
printf("%d\n", res);
return 0;
}
我还没听讲解,竟然和y总写的一模一样,好开心
👍
牛啊牛啊
wocao
最简单的一集
直接用优先队列的话能不能过呢
可以的,直接取负就可以了。
请问,为什么要取负值?
这样的话,按绝对值来看,优先队列里果子的重量就是从小到大排序了。
默认是大根堆
nb
Orz
$o(nlogn)$
代码需要处理一下边界, 当heap只有一个数的时候, res= heap.top。
题目要求了,n>1
只有一堆就不用合并了,res直接就是0
明明有等号
哈哈哈,我当时看的是>1😂
可能27天之前我看错了hhh
有没有可能只有一堆不需要费力气了,所以是0
hh
哈哈
## 以前是禁止用STL的。如果不用STL呢?
那就自己实现一个堆呗
你给人家难住了
把之前手写堆的代码搬过来
实现堆不算太难