带"反悔"的贪心-超市

题面:https://www.acwing.com/problem/content/description/147/

超市里有N件商品,每个商品都有利润pi和过期时间di,每天只能卖一件商品,过期商品(即当天di<=0)不能再卖。

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


第一眼看过去,呀,我应该先选利润大的。

但是因为选了利润大的,错失了一些利润还行的,而且就算 选了利润还行的也可以继续选利润大的怎么办?

这样看起来,保质期,利润,保质期+利润,这些指标排序都是不可行的。

那不如,我们就一路选过去。

我们先按照保质期从小到大排序,只要在保质期范围内我们就选。

终于,我们碰到了一个不能选的物品。

那我们从已经选了的物品中挑一个利润最小的,尝试着替换掉是否更优。

为什么可以替换呢?因为按照时间排序的话,能选前面的也一定能在同样的时间上选后面的。

优先队列可以很方便的实现。

#include <bits/stdc++.h>
using namespace std;
struct p{
    int v,d;
}a[10009];
priority_queue<int,vector<int>,greater<int> >q;
bool com(p a,p b){
    return a.d<b.d;
}
int n;
int main()
{
    while(cin>>n)
    {
        while(!q.empty())    q.pop();
        for(int i=1;i<=n;i++)    cin>>a[i].v>>a[i].d;
        sort(a+1,a+1+n,com);
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            if(q.size()<a[i].d)
                ans+=a[i].v,q.push(a[i].v);
            else if(!q.empty())
            {
                int r=q.top();
                if(r<a[i].v)
                {
                    q.pop();
                    ans=ans-r+a[i].v;
                    q.push(a[i].v);
                }
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/iss-ue/p/12487249.html