思路::很好的一个并查集的题,先用sort快排,把最值钱的商品放在第一个,然后先从当前最值钱的开始算,如果当天可以卖的话,就拿一天卖掉,如果有商品占了那一天,就往前一天寻找,并查集在这里就作为最靠近其保质期当天的那一天,如果其根为0,则表示该商品没有空闲的天卖出。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int f[11111]; //表示当前时间点上一个空闲时间,通过find函数可找到根节点,即空闲时间
struct node
{
int p,d;
}a[11111];
int find(int x)
{
if (f[x]==-1)
return x; //当前时间空闲
else
{
f[x]=find(f[x]);
return f[x];
}
}
bool cmp(node a,node b)
{
return a.p>b.p;
}
int main()
{
int u;
int ans;
while (~scanf ("%d",&u))
{
for (int i=0;i<u;i++)
scanf ("%d %d",&a[i].p,&a[i].d);
memset (f,-1,sizeof(f));
sort(a,a+u,cmp); //按价值从大到小排序
ans=0;
for (int i=0;i<u;i++)
{
int t;
t=find(a[i].d); //寻找其空闲时间点
if (t>0)
{
ans+=a[i].p; //若时间点合法,就卖出!
f[t]=t-1; //把该时间的合法时间往前推移1
}
}
printf ("%d\n",ans);
}
return 0;
}