【贪心】 Supermarket

传送门

题意

\(n\)件商品,每个商品有利润\(p[ i ]\)和过期时间\(d[ i ]\),每天只能卖一件商品,合理安排每天卖的商品,求最大收益

数据范围

\(\begin{array}{l}0 \leq N \leq 10000 \\ 1 \leq p_{i}, d_{i} \leq 10000\end{array}\)

题解

贪心做法,将所有商品按照过期时间的大小排序,从小到大依次将商品加入小根堆(利润为键值)
加入\(p[i]\)时:

  • 如果\(p[i]\)的时间大于堆中元素的个数,则放入堆
  • 如果当前时间等于堆中的元素个数,并且当前元素的利润大于小根堆的堆顶元素,将两者互换
  • 小于堆中的元素就不用加入
    • 前面的利润更大,所以加入会减少答案

Code

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define t first
#define val second

typedef pair<int,int>pii;
const int N=1e5+10;
int n;
pii goods[N];
void solve()
{
    rep(i,1,n+1) cin>>goods[i].val>>goods[i].t;
    sort(goods+1,goods+n+1);
    priority_queue<int,vector<int>,greater<int>>h;
    rep(i,1,n+1)
    {
        if(h.size()==goods[i].t && h.top() <= goods[i].val) h.pop(),h.push(goods[i].val);
        else if(goods[i].t>h.size()) h.push(goods[i].val);
    }
    int ans=0;
    while(h.size()) ans+=h.top(),h.pop();
    cout<<ans<<endl;
}
int main()
{
    while(cin>>n) solve();
}
posted @ 2020-05-23 00:38  Hyx'  阅读(138)  评论(0)    收藏  举报