POJ 1456 Supermarket【小根堆】【贪心】

传送门
题目大意:给定N个商品,每个商品有利润 P i P_i Pi和过期时间 d i d_i di,每天只能卖一个商品,过期的商品不能再卖,问如何安排商品,可以使收益最大。

思路:

对于每个时间t,应该在保证不卖出过期商品的前提下,尽量卖出利润前t大的商品。因此我们可用个小根堆来维护前t大的商品。
1.对于当前过期时间t等于当前堆的商品个数,则说明在目前方案前t天已经安排t个商品卖出。若当前商品的利润大于堆顶的利润,则替换掉。
2.对于当前过期时间t大于当前堆的商品个数,则直接把商品插入堆中
code:

#include
#include
#include
#include
using namespace std;
const int N=10010;
int n;
struct Product{
     
	int v,d;
}p[N];
bool cmp(Product a,Product b){
     
	if(a.d==b.d)
		return a.v>b.v;
	return a.d<b.d;
}
int main(){
     
	while(~scanf("%d",&n)){
     
		for(int i=0;i<n;i++){
     
			scanf("%d%d",&p[i].v,&p[i].d); 
		}
		sort(p,p+n,cmp);
		priority_queue<int,vector<int>,greater<int> > q;
		int ans=0;
		for(int i=0;i<n;i++){
     
			if(q.size()<p[i].d){
     
				 q.push(p[i].v);
				 ans+=p[i].v;
			}
			else{
     
				int t=q.top();
				if(t<p[i].v) {
     
					q.pop();
					q.push(p[i].v);
					ans-=t;
					ans+=p[i].v;
				}
			}
		}
		printf("%d\n",ans);
	}
}

你可能感兴趣的:(贪心,堆)