大顶堆,小顶堆的数据结构在我们需要处理在最大值和最小值的问题上给我们提供很好的工具。
例如:大鱼吃小鱼的游戏,给出一组非负元素代表每条鱼的F值,每一轮F值最小的一条鱼都会被F值第二小的鱼吃掉,并且新鱼F值为原来F值和吃掉的鱼F值之和:
F(新)=F(原来)+F(吃掉的)
问第m轮后最小的鱼F值为多少?(注:F值相同的话任意可选取任意一条)
我们可以利用小顶堆来实现:
每轮:弹出两个值,代表最小的和第二小的鱼,求和后插入;
最后弹出堆顶即为所要求的的值。
c++里使用优先队列创建:
//升序队列 小顶堆 最小值在堆顶
priority_queue <int,vector<int>,greater<int> > que;
//降序队列 大顶堆 最大值在堆顶
priority_queue <int,vector<int>,less<int> >que;
传入参数分别为:数据类型、容器类型、比较方式(默认是大顶堆)
常见操作有:
- empty 队列是否为空
- top 访问队头元素
- size 返回队列内元素个数
- push 插入元素到队尾 (并排序)
- pop 弹出队头元素
实现代码:
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
int main()
{
int n, m; //输入n、m n:鱼条数,m:进行吃的轮数
cin >> n >> m;
priority_queue <int, vector<int>, greater<int> > q; //小顶堆
//priority_queue <int, vector<int>, less<int> >q; //大顶堆
{
int x;
cin >> x;
q.push(x);
}
for (int i = 0; i < m;++i)
{
int last1 = q.top();
q.pop();
int last2 = q.top();
q.pop();
int sum = last1 + last2;
q.push(sum);
}
cout << q.top();
return 0;
}
例如:输入
5 3
5 7 11 9 3
(1)轮:7 8 9 11
(2)轮:9 11 15
(3)轮:15 20
输出:15