题目描述:

超市里有 N 件商品,每件商品都有利润 pi 和过期时间 di,每天只能卖一件商品,过期商品不能再卖。

求合理安排每天卖的商品的情况下,可以得到的最大收益是多少。

输入格式
输入包含多组测试用例。

每组测试用例,以输入整数 N 开始,接下来输入 N 对 pi 和 di,分别代表第 i 件商品的利润和过期时间。

在输入中,数据之间可以自由穿插任意个空格或空行,输入至文件结尾时终止输入,保证数据正确。

输出格式
对于每组产品,输出一个该组的最大收益值。

每个结果占一行。

数据范围
0≤N≤10000,
1≤pi,di≤10000
最多有 14 组测试样例

输入样例:
4 50 2 10 1 20 2 30 1

7 20 1 2 1 10 3 100 2 8 2
5 20 50 10
输出样例:
80
185

分析:

本题考察贪心,由于每件物品都有一个利润值和过期时间,显然利润值相同我们优先卖过期时间早的商品;或者过期时间相同时我们优先卖利润高的物品。但是并不能像一般的贪心那样一个排序就解决了问题,比如按照过期时间从小到大排序后,第一天我们卖第一天就过期的物品中利润最高的,第二天我们卖第一天过期的剩下物品和第二天会过期的物品中利润最高的物品,但是这就是最优解方案吗?显然不是,第二天过期的物品里利润最高和次高的物品的利润都可能高于第一天过期物品中最高的利润,这时候前两天都卖第二天会过期的物品显然利润更大。这说明我们不能单纯的按照过期时间或者利润取选择每天要卖的物品,而是要动态的维护每天要卖的物品。
本题就是要在排序后动态的选择每天要卖的物品,第一天能够获得的最大利润就是过期时间不小于1的物品中利润最大的,前两天能够获得的最大的利润中就是第一天卖最大利润不会过期的物品,第二天卖过期时间不小于1的物品中利润最大的物品,同时如果过期时间不小于1的物品中利润有高于第一天卖的利润的物品,就替换掉第一天卖的物品。可见我们枚举物品的顺序依旧是按照到期时间从小到大取枚举的,并且优先选择利润高的物品。
具体的方案就是:先对所有物品按照到期时间从小到大排序,然后维护一格每天要卖出物品的集合,首先如果第一件物品的到期时间不小于1,第一天就卖第一件物品;然后枚举第二件物品,如果第二件物品的到期时间不小于2,第二天就卖第二件物品,如果第三件物品的到期时间不小于3,就第三天卖第三件物品,如果第三件物品的到期时间是2,也将该物品放进前两天要卖物品的集合里,两天卖三件物品,所以要踢出三件物品中利润最小的那个,…,所以也就是,要卖出的物品集合里面的物品个数超过了当前枚举物品的到期时间,将该物品放进去后就要从集合里踢出利润最低的物品,否则直接加入集合就行。
对于排序后的第i个物品,di为其到期时间,要么待卖物品的集合里的物品数量不超过di,就可以直接将第i个物品加进去了;如果待卖物品里物品数量超过了di,那么一定只比di多1,加入集合后删掉利润最小的物品就可以了。为什么有这个性质呢?因为加入第i-1个物品时如果是直接加入没有删除物品,说明此时集合中物品的个数一定不超过第i - 1个物品的到期时间,而第i个物品的到期时间又不会早于上一个物品的到期时间,所以加入第i件物品后集合中元素个数至多比i的到期时间多1。举个例子,如果第三件物品到期时间是3,加进去后集合里恰好有三个元素,第四件物品的到期时间如果超过3,就可以直接加入,如果等于3,那么加进去后踢掉利润最低的那个后,集合中物品个数又是3了。
我们维护的这个集合只关心集合个数,集合元素的插入以及删除最小元素,所以可以使用小根堆来维护。

代码:

#include <iostream>
#include <algorithm>
#include <sstream>
#include <queue>
using namespace std;
const int N = 10005;
pair<int,int> a[N];
int main(){int n;while(cin>>n) {int p,d;for(int i = 0;i < n;i++) {cin>>p>>d;a[i] = {d,p};}sort(a, a + n);priority_queue<int, vector<int>, greater<int> > pq;for(int i = 0;i < n;i++) {d = a[i].first,p = a[i].second;pq.push(p);if(pq.size() > d)  pq.pop();}int res = 0;while(pq.size()) {res += pq.top();pq.pop();}cout<<res<<endl;}return 0;
}

AcWing 145 超市相关推荐

  1. AcWing 145.超市(二叉堆)

    题目链接 这道题在李煜东进阶指南里讨论了两种解法,都是基于贪心的思路,借助不同的数据结构,从而很好的达到目的.这里讨论二叉堆的解法. 看到这道题,想到了白书汽车加油问题,在某个站点加不加油取决于在后面 ...

  2. 145. 超市【小根堆 贪心】

    将商品按照时间从小到大排序.如果说此时物品的时间小于堆内的数量.说明堆内有几个物品是要过期的. 那么我们用小根堆来维护,直接取最小的删除即可. #include<bits/stdc++.h> ...

  3. 0x17.基础数据结构 - 二叉堆

    目录 一.二叉堆 二.例题 0.AcWing 145. 超市 AcWing 146. 序列(POJ 2442) 三.HuffmanHuffmanHuffman树 1.AcWing 148. 合并果子 ...

  4. 忽视警告_不要忽视下雨的风险2

    忽视警告 When I first saw Risk of Rain 2 a couple of months back in the Steam store, I didn't know what ...

  5. Three.js光源梳理3——平行光(DirectionalLight)

    平行光本质是一个方向向量,在shader中计算时直接与模型顶点的法线方向进行dot点乘操作. 如果L(平行光)的向量与N(顶点法线方向)一样(N Dot L=1),那么表示模型的这个点正对着光源,应该 ...

  6. 数据结构进阶之并查集

    1.初探并查集 例题1:AcWing 237.程序自动分析 这题的思路其实比较好想,只要先考虑所有等于的情况并合并,然后再看不等于的情况,看是否出现矛盾即可.但是这题显然是需要离散化的,但是离散化也很 ...

  7. Acwing145. 超市[C++题解]:贪心

    文章目录 本题思路 题目链接 本题思路 题目重述:给定n件商品的利润和过期时间,每天只能卖1件,问最大利润是多少. 题目思路: 贪心. 需要按照过期时间从早到晚排序.如果过期时间是3天的商品有≤3件商 ...

  8. Supermarket | 贪心

    Supermarket | 贪心 from poj 1456 from acwing 145 时间限制 :2s 内存限制:65M Description: A supermarket has a se ...

  9. Supermarket | 贪心 + 并查集

    Supermarket | 贪心 + 并查集 from poj 1456 from acwing 145 时间限制 :2s 内存限制:65M Description: A supermarket ha ...

最新文章

  1. poj 3321 Apple Trie
  2. Vue开发跨端应用(三)添加cordova
  3. html元素排序,HTML中的table里面的元素排序
  4. impala jdbc驱动执行impala sql的一个坑(不支持多行sql)
  5. 英文Ubantu系统安装中文输入法
  6. 使用Adobe Audition生成基本音频
  7. tensorflow实现回归
  8. Titon Toolkit – 非常强大的用户界面组件
  9. linux下ssh/scp无密钥登陆方法
  10. getconnection java_在MyEclipse用java写的一个GetConnection1.java,用于连接MySQL,却总是出错。(没有财富值了,见谅!)...
  11. 第七讲 塔木德破产分配法练习题
  12. DisplayLink 安装错误
  13. 她是北大“一个人的毕业照”主人公,2010 级古生物专业独苗,十年后转行搞起了 NLP...
  14. MT6580 Android8.1调试移植费恩格尔指纹驱动
  15. 京东风格的移动端Vue组件库NutUI2.0来啦
  16. java组件名词解释_简述Java EE三类组件的构成及运行环境。
  17. java获取weblogic路径_weblogic下java web项目获取根路径
  18. t14m4t:一款功能强大的自动化暴力破解工具
  19. matlab求数组转置,数组与矩阵运算 - MATLAB Simulink - MathWorks 中国
  20. STM8S 红外解码+低功耗处理

热门文章

  1. java currency 默认_Java Currency.equals方法代码示例
  2. 一度智信:电商网店推广技巧分享
  3. Kinect安装与使用(一)
  4. 丽怡酒店品牌彰显运营实力,领跑中端酒店赛道
  5. 极路由b70路由器虚拟服务器,极路由B70刷固件详细步骤说明(整合其它坛友经验)-少走弯路,造福坛友...
  6. procast2021学习笔记
  7. Java接入微信支付超级详细教程——从入门到精通
  8. java接收任意键继续_正确实现“按任意键继续”功能
  9. python适合做网页吗_python是否适合网页编程详解
  10. word自动消除html标签,如何将Word转换为网页html格式的方法(附代码清理方法)