POJ 1456-Supermarket(贪心+并查集)

Supermarket

Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 23513 Accepted: 10318

Description

A supermarket has a set Prod of products on sale. It earns a profit px for each product x∈Prod sold by a deadline dx that is measured as an integral number of time units starting from the moment the sale begins. Each product takes precisely one unit of time for being sold. A selling schedule is an ordered subset of products Sell ≤ Prod such that the selling of each product x∈Sell, according to the ordering of Sell, completes before the deadline dx or just when dx expires. The profit of the selling schedule is Profit(Sell)=Σx∈Sellpx. An optimal selling schedule is a schedule with a maximum profit.
For example, consider the products Prod={a,b,c,d} with (pa,da)=(50,2), (pb,db)=(10,1), (pc,dc)=(20,2), and (pd,dd)=(30,1). The possible selling schedules are listed in table 1. For instance, the schedule Sell={d,a} shows that the selling of product d starts at time 0 and ends at time 1, while the selling of product a starts at time 1 and ends at time 2. Each of these products is sold by its deadline. Sell is the optimal schedule and its profit is 80.
在这里插入图片描述
Write a program that reads sets of products from an input text file and computes the profit of an optimal selling schedule for each set of products.
Input

A set of products starts with an integer 0 <= n <= 10000, which is the number of products in the set, and continues with n pairs pi di of integers, 1 <= pi <= 10000 and 1 <= di <= 10000, that designate the profit and the selling deadline of the i-th product. White spaces can occur freely in input. Input data terminate with an end of file and are guaranteed correct.
Output

For each set of products, the program prints on the standard output the profit of an optimal selling schedule for the set. Each result is printed from the beginning of a separate line.

Sample Input

4 50 2 10 1 20 2 30 1

7 20 1 2 1 10 3 100 2 8 2
5 20 50 10

Sample Output

80
185

超市里有N个商品. 第i个商品必须在保质期(第di天)之前卖掉, 若卖掉可让超市获得pi的利润.
每天只能卖一个商品.
现在你要让超市获得最大的利润.

Input
多组数据.
每组数据第一行为一个整数N (0 <= N <= 10000), 即超市的商品数目
之后N行各有两个整数, 第i行为 pi, di (1 <= pi, di <= 10000)

Output
对于每一组数据, 输出当前条件下超市的最大利润

Sample Input
4
50 2
10 1
20 2
30 1

7
20 1
2 1
10 3
100 2
8 2
5 20
50 10

Sample Output
80
185

题目大意:给出n种商品,每种都有价值和保质期,一天只能卖一种商品,求所有商品都过期之前能获得的最大利润。

解题思路:这道题可以用贪心和并查集的思路去想,设一个结构体node存储每个商品的价值和保质期,因为想获得最大利润,就得每天都卖价值最高的商品,因为每个商品都有保质期,所以每天所获得的最大利润不一定是一样的:举个栗子 保质期为1的商品价值 20 30 50,保质期为2的商品有50 60 70,因为60 和 70 是第二天才过期,如果第一天不卖掉20 30 50 中的其中一个,那么到了第二天都会过期,所以第一天我们选择50的商品,第二天我们选择70的商品就可以获得最大利润,先把所有商品信息存入一个结构体数组,根据价值降序给数组排序,然后用并查集的思想,因为价值是降序的,假设价值最高的商品为70,他的保质期为2,则说明他是第二天的最大价值,第二天就不能用了,如果还有商品保质期为2(60 2),那肯定不行,就只能去2-1 第一天卖了。AC代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int _max=1e5+50;
struct node {int p,d;};
int f[_max];
node a[_max];
bool cmp(node a,node b) {return a.p>b.p;}
int find(int x)
{
	if(f[x]==-1)
	  return x;
    return f[x]=find(f[x]);
}
int main()
{
	ios::sync_with_stdio(false);
	int n;
	while(cin>>n)
	{
		memset(f,-1,sizeof f);//初始化为-1表示一开始都没被占用
		for(int i=0;i<n;i++)
		  cin>>a[i].p>>a[i].d;
		sort(a,a+n,cmp);//按照价值降序
		int sum=0;
		for(int i=0;i<n;i++)
		{
			int x=find(a[i].d);//检查该商品的保质期之内是否能销售
			if(x>0)
			{
				f[x]=x-1;//表示这天已经被占用了  自己减一
				sum+=a[i].p;
			}
		}
		cout<<sum<<endl;
	}
	return 0;
}
posted @ 2020-03-11 16:54  Hayasaka  阅读(54)  评论(0编辑  收藏  举报