【堆】B002_AW_超市(贪心+最小堆)
超市里有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
方法一:贪心+小根堆
每天只能卖出一种商品,首先时间得有序才能再对利润做出决策,这里先对时间升序排序;当遇到新商品 x 时,且第 j 天能卖的商品个数已经达到了 j 个(即加入该商品后是j+1个),那么就对比商品 x 和这 1~j 天中利润最小的商品的利润,如果 x.p 大于它,那么这个商品就不要了了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node{
ll p, d;
};
bool cmp(const node &a, const node &b){
return a.d < b.d;
}
const int N=1e5+5;
node A[N];
int main() {
std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n;
while (cin>>n) {
for (int i=0; i<n; i++) cin>>A[i].p>>A[i].d;
priority_queue<ll, vector<ll>, greater<ll>> minQ;
sort(A, A+n, cmp);
for (int i=0; i<n; i++) {
minQ.push(A[i].p);
if (minQ.size()>A[i].d) {
minQ.pop();
}
}
int ans=0;
while (!minQ.empty()) {
ans+=minQ.top(); minQ.pop();
}
cout << ans << '\n';
}
return 0;
}
复杂度分析
- Time:\(O(nlogn)\),
- Space:\(O(n)\),