优先队列(含详细解释和例题)

一、优先队列的简单介绍

        优先队列是一种特殊的队列,队列中元素都有一定的优先级,元素的出队顺序是根据它们的优先级来确定的。

        头文件为#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;
}

  • 16
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值