优先队列及应用

优先队列及应用

优先队列定义:
能够完成以下操作的数据结构叫做优先队列:

  • 插入一个数值
  • 取出最小或最大值

为实现优先队列,需用到数据结构“

堆及相关操作
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中有相关函数因此非常方便
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值