一、优先队列的简单介绍
优先队列是一种特殊的队列,队列中元素都有一定的优先级,元素的出队顺序是根据它们的优先级来确定的。
头文件为#include<queue>中,优先队列包含队列的所有操作,只是在队列的基础上加上一个排序,优先级高的先出队。
定义优先队列:priority_queue<Type, Container, Functional>
1.Type:存储在优先队列中的元素类型。
2.Container:用于底层存储的容器类型。STL中默认使用的是vector
,但你也可以使用任何提供随机访问迭代器和支持front()
、push_back()
以及pop_back()
方法的容器。其中vector(向量)可以理解为长度可变的数组。定义格式为vector<int> V。
3.Functional:一个比较函数对象类型,用于比较两个元素的优先级。默认情况下,使用的是less<Type>
,这意味着队列的顶部是最大元素,实现了一个最大优先队列,使用greater<Type>实现了一个最小优先队列。
priority_queue<pair<int, int> > a;创建了一个整数对(两个整数)的优先队列。每个整数对都有两个元素。在这个优先队列中,元素的优先级基于默认的比较方法,即首先根据第一个元素的降序排列,如果第一个元素相同,则根据第二个元素的降序排列。
二、优先队列的常用函数
1.push(const value_type& val)向优先队列中插入一个元素,该元素的位置会根据其优先级自动确定。
q.push(10);
2.pop()移除优先队列顶端的元素(即优先级最高的元素)。
q.pop();
3.top()返回优先队列顶端的元素的引用,但不移除它。
int a = pq.top();
4.empty()检查优先队列是否为空。如果为空,则返回 true
;否则,返回 false
。
5.size()返回优先队列中的元素个数。
6.emplace()在优先队列中的适当位置直接构造一个元素,避免了额外的复制或移动操作。
pq.emplace(20); // 直接在优先队列中构造元素20
三、优先队列相关例题
1.有一个长度为n 的数组(n 是 10 的倍数),每个数 ai 都是区间[0,9]中的整数。小明发现数组里每种数出现的次数不太平均,而更改第之个数的代价为bi,他想更改若干个数的值使得这 10 种数出现的次数相等(都等于n/10 ),请问代价和最少为多少。
输入格式
输入的第一行包含一个正整数 n。
接下来 几 行,第i行包含两个整数 ai,bi,用一个空格分隔。
输出格式
输出一行包含一个正整教表示答案
分析:这个用到贪心的思想,我们定义一个vector,其中包含10个优先队列,让每个数的队列中最小的代价放到顶部,当某个数出现的个数大于n/10时,继续删除它对应的队列中顶部元素,每次删除的元素为局部最优的选择,直到所有元素的次数都为n/10。
#include<iostream>
#include<queue>
using namespace std;
int main()
{
int n,sum=0;
cin >> n;
vector<priority_queue<int, vector<int>, greater<int>>> v(10); //这个 vector 容纳了10个优先队列,并且这些优先队列的元素按照
//从小到大的顺序排列
for(int i = 0; i < n; ++i){
int a, b;
cin >> a >> b;
v[a].push(b); //存入每个数的代价
}
for(int i = 0; i < 10; ++i){
while(v[i].size() > n / 10){
sum += v[i].top();
v[i].pop();
}
}
cout << sum;
return 0;
}