思路
例子
- 它一定是一颗完全二叉树,除叶子结点外,每一个点都有俩个儿子 。(其中
所有的叶子结点是要合并的点,内部的点都有由某些点合并过来的点
)
结果
- 只需要在完全二叉树中,选一个下述式子,权值最小的数。
- 权值 =
叶节点的值 * 叶节点到根节点的路径
步骤
- 在所有的数中,选择最小的俩个数,
一定是整个树里面深度最深
的的俩个点,并且可以(不是一定)互为兄弟
- 最小的俩个点一定是深度最深的,如果深度不是最深的,就把俩个点换到深度最深的位置,则它整体的权值就会变小---->
权值最小的点,一定是深度最深
题目
代码
#include <iostream>
#include <queue>
using namespace std;
int n;
priority_queue<int, vector<int>, greater<int> > heap; //定义一个名为q的小根堆
int main()
{
scanf("%d", &n);
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(); //取第二小值
int c = a + b; //消耗体力值 与 新堆果子数
res += c;
heap.push(c); //插入新果子堆
}
printf("%d\n", res);
return 0;
}