Fork me on GitHub

【luoguUVA1316】 Supermarket--普通并查集+贪心

 

题目描述

有一个商店有许多批货,每一批货又有N(0<=N<=10^4 )个商品,同时每一样商品都有收益P_iPi ,和过期时间D_iDi (1<=Pi,,Di <=10^4 ),一旦超过了过期时间,商品就不能再卖。

你要做的就是求出每批货最多能得到多少收益。

输入输出格式

输入格式

多组数据,每组先给出一个整数N,表示这批货的商品个数。

然后有N对数,每对数有两个用空格隔开的正整数P_i,D_i ,表示第i个商品的收益和过期时间。相邻两对数之间用空格隔开。

输入以一个文件终止符结束,并且保证所有输入数据正确。

输出格式

对于每组数据,输出一行一个整数表示该批货物能卖出的最大价格。

感谢@Rye_Catcher 提供的翻译

题目描述

PDF

输入格式

输出格式

输入输出样例

输入 #1
4 50 2 10 1 20 2 30 1
7 20 1 2 1 10 3 100 2 8 2 5 20 50 10
输出 #1
80 
185
思路:这道题是一个贪心,我们可以维护一个大根堆,按价值排序
之后,已过期当天为期限,每次从大往小扫,如果该地方(过期当天)
已经有值,则往前推,并查集可维护前面可以占用的时间》
代码:
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<queue>
#include<cstring>
using namespace std;
int n,cnt,sum;
bool lim[100000];
struct node{
	int val,t;
	friend bool operator < (const node &a,const node &b)
	{
		return a.val < b.val;
	}
}e[100000];
priority_queue <node> q;
int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		memset(e,0,sizeof(e));
		memset(lim,0,sizeof(lim));
		sum=0;
		for(int i=1;i<=n;i++)
		{
			scanf("%d%d",&e[i].val,&e[i].t);
			q.push( (node) {e[i].val,e[i].t}  );
		}
//		for(int i=1;i<=n;i++)
//		{
//			node p=q.top();
//			q.pop();
//			int aa=p.val;
//			cout<<aa<<" ";
//		}
//		cout<<endl;
		for(int i=1;i<=n;i++)
		{
			node a=q.top();
			q.pop();
			int x=a.t;
			if(lim[x])
			{
				while(lim[x])x--;
			}
			if(x>0)sum+=a.val,lim[x]=1;
		}
		printf("%d\n",sum);
	}
	return 0;
}

  



posted @ 2019-09-19 14:11  yelir  阅读(218)  评论(0编辑  收藏  举报