[Ybtoj Chapter 10 Example 5] Supermarket shopping [Combined check collection]

Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here


Problem-solving ideas

First of all, we can easily think of the greedy thought of this question. Sort all commodities in order of income, and make a decision on each commodity from the front to the back. For the i-th commodity, if there is no commodity sold on a certain day within the expiration date, then Select the last day that the product can be sold to sell it, and then set that day as sold. Process: enumerate the dates from the expiration date of the product forward, and find the answer once you encounter a date that is not sold. This time complexity is O(N 2) O(N^2)O N2

Consider optimizing time complexity:
We found that the bottleneck lies in finding the last date when each product can be sold. We can abstract each date as a collection, and the representative of the collection is the only date on which no goods have been sold in the entire collection. It is not difficult to find that the representative of each collection must be the smallest of the collection dates. These dates can obviously be used and checked for maintenance.

SO, the process of
finding the last date that each product can be sold is: find out the representative element of the collection where the product expires, if the representative element of the collection is not 0 00 , the product is sold on the day of its representative element. And merge this collection into the collection where the day before that day (representing the day before the element).


Code

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<bitset>
using namespace std;

int n,p[10010],d[10010],fa[10010],maxn,ans;

struct c{
    
    
	int p,d;
}a[10010];

bool cmp(c l,c r)
{
    
    
	return l.p>r.p;
}

int find(int x)
{
    
    
	if(fa[x]==x)return x;
	else return fa[x]=find(fa[x]);
}

int main(){
    
    
	while(scanf("%d",&n))
	{
    
    
		maxn=0,ans=0;
		for(int i=1;i<=n;i++)
		{
    
    
			scanf("%d%d",&a[i].p,&a[i].d);
			maxn=max(maxn,a[i].d); 
		}
		sort(a+1,a+n+1,cmp);//从大到小
		for(int i=1;i<=maxn;i++)fa[i]=i;
		for(int i=1;i<=n;i++)
		{
    
    
			int x=find(a[i].d);
			if(x!=0)//看过期时间
			{
    
    
				ans+=a[i].p;
				fa[x]=x-1;//并入代表元素的前一天
			}
		}
		printf("%d\n",ans);
	}
}


Guess you like

Origin blog.csdn.net/kejin2019/article/details/115254534