算法学习笔记(STL容器-priority_queue)

作为一个实用主义,此篇暂时不介绍堆的具体结构,只快速地帮助读者了解如何使用。

p r i o r i t y _ q u e u e priority\_queue priority_queue:优先队列,是一种堆。

大根堆:

p r i o r i t y _ q u e u e < i n t , v e c t o r < i n t > , l e s s < i n t > >   q priority\_queue<int,vector<int>,less<int>>\ q priority_queue<int,vector<int>,less<int>> q

或者直接写成:

p r i o r i t y _ q u e u e < i n t >   q priority\_queue<int> \ q priority_queue<int> q

因为优先队列默认为大根堆。对他操作时一般只在堆顶操作,因为堆顶有一个特性就是:堆顶始终是堆中最大的元素,也就是 q . t o p ( ) q.top() q.top()是堆中最大的元素。

小根堆写法:

p r i o r i t y _ q u e u e < i n t , v e c t o r < i n t > , g r e a t e r < i n t > >   q priority\_queue <int, vector<int>, greater<int>>\ q priority_queue<int,vector<int>,greater<int>> q

与大根堆一样,只不过堆顶变成了堆中最小的元素。

对堆的操作:

  1. q . s i z e ( ) q.size() q.size():返回堆中元素的个数。
  2. q . e m p t y ( ) q.empty() q.empty(): 判断堆中是否为空,空则返回1,否则返回0。
  3. q . p o p ( ) q.pop() q.pop():弹出堆顶元素。
  4. q . t o p ( ) q.top() q.top():返回堆顶元素。
  5. q . p u s h ( ) q.push() q.push():往堆中添加元素。

总结下来,堆的用途就是可以很好的维护一些元素中的最小值或最大值。

结合题目理解一下:

题目链接

题目描述

你有一个菜篮子。

接下来 Q Q Q次操作,每次操作如下:

  1. “1 x”,将一个重量为 x x x的菜放入到菜篮子中。
  2. “2”,将菜篮子中重量最大的菜丢掉(如果菜篮子为空,则跳过)。

Q Q Q次操作后,菜篮子中剩下的菜的总重量。

输入描述

第一行一个整数 Q Q Q,表示操作次数。 ( 1 ≤ Q ≤ 1 0 5 ) (1≤Q≤10^5) (1Q105)

接下来 Q Q Q行,每行一条操作。 ( 1 ≤ x ≤ 1 0 9 ) (1≤x≤10^9) (1x109)

输出描述

一个整数表示答案

利用优先队列,当输入操作 1 1 1时把 x x x丢进优先队列里,并将x加进答案。当输入操作 2 2 2时,在答案里减去 x x x,再将堆顶弹出即可。

#include<bits/stdc++.h>
using ll = long long;
using namespace std;

int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    
    priority_queue<ll> pq;
    ll sum = 0;
    int q; cin >> q;
    while(q--)
    {
      	int op; cin >> op;
        if(op == 1)
        {
            ll x; cin >> x;
            pq.push(x);
            sum += x;
        }
        if(op == 2 && pq.size())
        {
            sum -= pq.top();
            pq.pop();
        }
    }
    cout << sum << '\n';
    
    return 0;
}

实际应用:动态维护数组内的最大值或最小值。

更详细内容可以看看starrycoding中的算法基础课,联系笔者可以争取半价(真妹卖课,只是这课真的很好,推荐给大家)。

后续内容持续更新中~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值