【堆】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)\)
posted @ 2020-09-09 10:31  童年の波鞋  阅读(181)  评论(0编辑  收藏  举报