AcWing 145. 超市(贪心)

题干:

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

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

输入包含多组测试用例。

每组测试用例,以输入整数N开始,接下里输入N对pi和di,分别代表第i件商品的利润和过期时间。

在输入中,数据之间可以自由穿插任意个空格或空行,输入至文件结尾时终止输入,保证数据正确。

0≤N≤100000
1≤pi,di≤10000

思路:

因为存在过期时间,并且一天只能买一个,所以可以考虑先按过期时间从小到大排序,这样可以保证卖出商品都不会过期。
然后考虑利益最大化的情况:
如果当前商品的过期时间大于当前天数,则计划当天卖出
如果当前商品的过期时间等于当前天数,则考虑我们可以将所有计划卖出的商品中价值最小的与当前的比较,如果当前的比较大,则我们将最小的替换掉(注意要重新排序了)(其实就是个小根堆) ;
过期时间小于当前天数,都过期了肯定不能卖啊。
然后注意下数据范围。

#include 
#include 
#include 
#include 
#include 
#include 
#define ll unsigned long long
using namespace std;
pair<int,int> t[10100];
priority_queue<int,vector<int >,greater<int> >q;
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF){
        memset(t,0,sizeof(t));
        for(int i=0;i<n;i++){
            scanf("%d%d",&t[i].second,&t[i].first);
        }
        sort(t,t+n);
//        for(int i=0;i
//            printf("%d %d\n",t[i].second,t[i].first);
//        }
        for(int i=0;i<n;i++){
            if(t[i].first>q.size())
                q.push(t[i].second);
            else if(t[i].first==q.size()&&t[i].second>q.top()){
                q.pop();
                q.push(t[i].second);
            }
        }
        ll ans=0;
        while(!q.empty()){
            ans+=q.top();
            q.pop();
        }
        printf("%lld\n",ans);
    }
    return 0;
}


你可能感兴趣的:(暑假训练题,二叉堆,贪心,二叉堆)