【贪心】 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();
}

浙公网安备 33010602011771号