超市(贪心算法+STL运用)

H - 超市

超市里有N个商品. 第i个商品必须在保质期(第di天)之前卖掉, 若卖掉可让超市获得pi的利润.
每天只能卖一个商品.
现在你要让超市获得最大的利润.
(原题说明过于抽象)

Input
多组数据.
每组数据第一行为N, 即超市的商品数目
之后N行数字. 第i行为 pi, di
N , pi, di <= 10000

Output
对于每一组数据, 输出当前条件下超市的最大利润

Sample Input
4
50 2
10 1
20 2
30 1

7
20 1
2 1
10 3
100 2
8 2
5 20
50 10
Sample Output
80
185

思路:
如果我们保质期最长是n天,那么我们在第n天的时候,卖出去的一定是保质期为n天的商品中最贵的那个,假如我们有如下数据:

保质期:利润
1: 2 20
2: 8 100
3: 10
10: 8 9
12: 7,10 15 30

那么第12天,我们卖出去的一定是30
30一定是在第12天卖出去的,那第11天卖的商品,就要把30去掉,然后再来判断。
由于没有保质期为11天的,所以我们接着卖保质期大于11天的最贵的商品:15
直到第10天,保质期为12天的商品还剩下7和10,保质期为10天的商品有8和9:

保质期:利润
1: 2 20
2: 8 100
3: 10
10: 8 9
12: 7,10

很明显要卖10嘛,因为10最大,所以我们得到了解题的方法了,从后面逆推,因为第n天卖出去的商品是确定了的,我们我们就从这个突破点一路逆推上来。
实现的时候用了 map优先队列
AC代码:

#include <cstdio>
#include <queue>
#include <map>
using namespace std;
int main(void)
{
    int n;
    while (scanf("%d", &n) != EOF)
    {
        map<int, priority_queue<int>> m;
        int day, value;
        while (n--)
        {
            scanf("%d%d", &value, &day);
            m[day].push(value);
        }
        int ans = 0;
        map<int, priority_queue<int>>::reverse_iterator it = m.rbegin(), end = m.rend(); //从最后一天开始卖
        priority_queue<int> que;
        for (int n = it->first; n >= 1; n--) //递减遍历天数
        {
            if (it != end && it->first >= n) //如果保质期大于现在的天数
            {
                while (it->second.size())
                    que.push(it->second.top()), it->second.pop();
                it++;
            }
            if (que.size())
                ans += que.top(), que.pop();
        }
        printf("%d\n", ans);
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值