C++ STL:优先队列的使用详解
堆是一个很重要的数据结构,那么我们如何更加简洁的去写大根/小根堆呢?
对于很多语言来说,只能一步一步手打,但是对于C++来说,写大根小根堆就简便得多,因为C++中有一个容器叫做priority_queue,这个容器和queue都包含在头文件<queue>中,priority_queue容器叫做可以模拟优先队列,这个容器可以将你输入的数据按顺序储存在容器里,插入元素和删除元素操作的时间复杂度都是log N,但是查询堆顶元素(最值)的时间复杂度是O(1),插入和删除用:a.push(x)和a.pop()来进行,返回堆顶元素的操作是a.top(),由于优先队列自身的特性,它本身只能写大根堆,但是如果我们将输入时的数据都变为它的相反数,输出时再变为相反数,这样就可以将优先队列变成小根堆,当然我们也可以重载‘<’来实现。
下面介绍一道相关的水题:
题目描述
在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。
每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过 n-1n−1 次合并之后, 就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。
因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为 11 ,并且已知果子的种类 数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。
例如有 33 种果子,数目依次为 11 , 22 , 99 。可以先将 11 、 22 堆合并,新堆数目为 33 ,耗费体力为 33 。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为 1212 ,耗费体力为 1212 。所以多多总共耗费体力 =3+12=15=3+12=15 。可以证明 1515 为最小的体力耗费值。
输入格式
共两行。
第一行是一个整数 n(1\leq n\leq 10000)n(1≤n≤10000) ,表示果子的种类数。
第二行包含 nn 个整数,用空格分隔,第 ii 个整数 a_i(1\leq a_i\leq 20000)ai(1≤ai≤20000) 是第 ii 种果子的数目。
输出格式
一个整数,也就是最小的体力耗费值。输入数据保证这个值小于 2^{31}231 。
输入输出样例
3
1 2 9
15
说明/提示
对于30%的数据,保证有n \le 1000n≤1000:
对于50%的数据,保证有n \le 5000n≤5000;
对于全部的数据,保证有n \le 10000n≤10000。
这是2004年NOIP提高组的题,我们根据贪心思想,每次将现在有的果子堆最小的两个结合,可以保证每一步都是最优,我们可以用小根堆来实现,每次弹出两个最小的元素,然后再将他们合并后的果子堆得值再放入堆中。
Code:
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
priority_queue<int> a;
long long ans=;
int main(){
int n,x;
cin>>n; for(int i=;i<=n;i++) cin>>x,a.push(-x);
for(int i=;i<n;i++){
int k=-a.top();
a.pop();
int j=-a.top();
a.pop();
ans+=k+j;
a.push(-k-j);
}
cout<<ans<<endl;
}
谢谢阅读
C++ STL:优先队列的使用详解的更多相关文章
- C++中的STL中map用法详解(转)
原文地址: https://www.cnblogs.com/fnlingnzb-learner/p/5833051.html C++中的STL中map用法详解 Map是STL的一个关联容器,它提供 ...
- STL priority_queue 常见用法详解
<算法笔记>学习笔记 priority_queue 常见用法详解 //priority_queue又称优先队列,其底层时用堆来实现的. //在优先队列中,队首元素一定是当前队列中优先级最高 ...
- 跟我一起学STL(2)——vector容器详解
一.引言 在上一个专题中,我们介绍了STL中的六大组件,其中容器组件是大多数人经常使用的,因为STL容器是把运用最广的数据结构实现出来,所以我们写应用程序时运用的比较多.然而容器又可以序列式容器和关联 ...
- STL stack 常见用法详解
<算法笔记>学习笔记 stack 常见用法详解 stack翻译为栈,是STL中实现的一个后进先出的容器.' 1.stack的定义 //要使用stack,应先添加头文件#include &l ...
- STL queue 常见用法详解
<算法笔记>学习笔记 queue 常见用法详解 queue翻译为队列,在STL中主要则是实现了一个先进先出的容器. 1. queue 的定义 //要使用queue,应先添加头文件#incl ...
- STL map 常见用法详解
<算法笔记>学习笔记 map 常见用法详解 map翻译为映射,也是常用的STL容器 map可以将任何基本类型(包括STL容器)映射到任何基本类型(包括STL容器) 1. map 的定义 / ...
- STL set 常见用法详解
<算法笔记>学习笔记 set 常见用法详解 set是一个内部自动有序且不含重复元素的容器 1. set 的定义 //单独定义一个set set<typename> name: ...
- STL vector常见用法详解
<算法笔记>中摘取 vector常见用法详解 1. vector的定义 vector<typename> name; //typename可以是任何基本类型,例如int, do ...
- STL之string类详解
通过在网站上的资料搜集,得到了很多关于string类用法的文档,通过对这些资料的整理和加入一些自己的代码,就得出了一份比较完整的关于string类函数有哪些和怎样用的文档了!下面先罗列出string类 ...
- STL pair 常见用法详解
<算法笔记>学习笔记 pair 常见用法详解 //pair是一个很实用的"小玩意",当想要将两个元素绑在一起作为一个合成元素, //又不想因此定义结构体时,使用pair ...
随机推荐
- java学习day3运算符
一.算数运算符 1.对于除号“/”,它的整数除和小数除是有区别的:当整数除以整数的时候,会把结果的小数部分舍弃,只保留整数部分,例如: int x=3510; x=x/1000; 输出结果为x=3; ...
- dfs(魔力转圈圈)
http://oj.jxust.edu.cn/contest/problem?id=1563&pid=4 题目描述 Storm有一个m行n列的整数矩阵. 他会从(1,1)开始,顺时针螺旋访问该 ...
- HDU2188选拔自愿者
悼念512汶川大地震遇难同胞--选拔志愿者 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- 51nod - 1586 - 约数和 - 打表 - 思维
https://www.51nod.com/Challenge/Problem.html#problemId=1586 一眼看过去居然一点思路都没有的,一言不合就打表,打贡献表. #include & ...
- [THUPC2018] 弗雷兹的玩具商店
link $solution:$ 好久没写数据结构了,那就写道简单题吧! 可以发现 $m\leq 50$,所以可以去取在 $[l,r]$ 中当价格相同时愉悦值最高的做完全背包 $dp$ . 发现修改价 ...
- hihocoder1954 : 压缩树
传送门 首先求出缩一个点 $x$ 的贡献,就是缩 $x$ 的父亲的贡献加上 $x$ 的子树多减少的深度 假设此时缩父亲的贡献已经考虑过了,那么 $x$ 的子树多减少的深度就是子树的节点数 注意此时要满 ...
- 将地址转成blob格式(服务器下运行)
<div id="forAppend" class="demo"></div> <script> var eleAppend ...
- java反射, 不看你可别后悔
开发中, 难免遇到些私有的属性和方法, 就好比下面的实体一样, 我们该怎么获得她, 并玩弄于手掌呢? 我们先来个实体瞧瞧, 给你个对象你也new不了, hahaha- 单身wang public cl ...
- MVC调用函数function.php
<?php //控制器的调用函数C function C($name, $method){ require_once('/libs/controller/'.$name.'Controller. ...
- 2019-8-14-win10-使用-SMB-v1
title author date CreateTime categories win10 使用 SMB v1 lindexi 2019-08-14 08:55:55 +0800 2018-2-13 ...