优先队列及应用
优先队列定义:
能够完成以下操作的数据结构叫做优先队列:
- 插入一个数值
- 取出最小或最大值
为实现优先队列,需用到数据结构“堆”
堆及相关操作
https://blog.csdn.net/qq_45769877/article/details/104077952
但大部分情况并不需要自己实现堆:
C++中的STL中priority_queue有优先队列的相关操作
//头文件
#include"queue"
using namespace std;
//声明
priority_queue<int> pque;
//进堆
pque.push(1);
//堆是否为空
pque.empty();
//堆头出堆
pque.pop();
//获得堆顶元素
pque.top();
//堆的长度
pque.size();
有一个问题时:程序默认为大根堆
如何设定大根堆和小根堆:greater()和less()函数
定义:Type为元素类型,Container在STL中默认为vector,Functional 是比较的方式
priority_queue<Type, Container, Functional>
//greater()和less()的头文件
#include"functional"
#include"queue"
using namespace std;
//声明小根堆
priority_queue<int, vector<int>, greater<int>> pque1;
//声明大根堆
priority_queue<int, vector<int>, less<int>> pque2;
相关题目:Expedition
驾驶一辆汽车行驶L距离到达一个小镇。开始时卡车有P单位汽油,卡车每开一单位距离耗费1单位汽油,途中有N个加油站,第i个加油站距起点Ai单位,每个加油站可以加Bi单位的汽油。假设卡车燃料箱无限大,问卡车是否可以到达终点?如果可以,至少加多少次油?否则输出-1。
示例:
N=4,L=25,P=10
A={10,14,20,21}
B={10,5,2,4}
这里认为
在到达加油站i时,就获得了一次在之后任何时候都可以加Bi单位汽油的权力”
希望加油次数尽可能的少,因此当燃料为0时,使用之前加油的权力,选择一个储量最大的加油站
以通过前两个加油站为例:
设油量为tank,gap[]为相邻两加油站的距离,a[]为加油站距起点的距离,b[]为各加油站的加油量
- 初始tank>=gap[0],因此车不加油可到达a[0]加油站
- 到达a[0]时,tank=0,并且得到a[0]加油站加b[0]油机会,将其加入到声明好的priority_queue中
- 但此时tank<gap[1],也就是说在不加油的情况下不能到达a[1],因此通过queue选择油量最大值加给tank
- 此时便可到达a[1]
- …… ……
#include"stdio.h"
#include"stdlib.h"
#include"queue"
#include"functional"
using namespace std;
#define MAX 100
int N, L, P;
int a[MAX], b[MAX];
priority_queue<int> pque;
int solve() {
int ans = 0;
int gap[MAX];
a[N] = L;
b[N] = 0;
gap[0] = a[0];
for (int i = 1; i <= N; i++) {
gap[i] = a[i] - a[i - 1];
}
for (int i = 0; i <= N; i++) printf("%d\n", gap[i]);
int n = 0;
int tank = P;
while (n <= N) {
if (tank >= gap[n]) {
pque.push(b[n]);
printf("%d\n", b[n]);
}
else {
while (tank < gap[n]) {
if (pque.empty()) return -1;
else {
tank += pque.top();
pque.pop();
ans++;
}
}
}
tank -= gap[n];
n++;
}
return ans;
}
int main(){
scanf_s("%d%d%d", &N, &L, &P);
for (int i = 0; i < N; i++) {
scanf_s("%d%d", &a[i], &b[i]);
}
printf("%d", solve());
system("pause");
}
}
总结
- 优先队列与堆的时间复杂度相同为O(logn)
- 在一些需要插入数据,选择最大和最小数据上具有明显的优势(例如:huffman编码)
- 而且在STL中有相关函数因此非常方便