题目大意
给你一个超市,每个物品价格为p,过d天就过期了,每天最多卖一个物品,问最大收益。
解析:用到一个很神奇的并查集,先把价格排一下序,有一个很简单的结论,对于每一个要卖出的物品,能拖就拖,把时间让给期限更短的物品。那么对于物品i,如果它的期限为d,就查询d的树根r,如果r>0,就把物品i在第r天卖出并记录答案,然后把r和r-1合并(令r为r-1的儿子)。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct point
{
int p;
int d;
}a[10010];
int n,ans;
int father[10010];
int cmp(point a1,point a2)
{
return a1.p>a2.p;
}
int find(int x)
{
if(x==father[x])
return x;
return father[x]=find(father[x]);
}
void unionn(int x,int y)
{
father[x]=y;
}
int main()
{
while(scanf("%d",&n)==1)
{
ans=0;
int maxn=0;
memset(a,0,sizeof(a));
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+1+n,cmp);
for(int i=1;i<=maxn;i++)
father[i]=i;
for(int i=1;i<=n;i++)
{
int r=find(a[i].d);
if(find(r)>0)
{
unionn(r,r-1);
ans+=a[i].p;
}
}
printf("%d\n",ans);
}
return 0;
}