supermarket

题目链接

题意:给你n个商品,商品的利润和商品的过期时间,商品必须在过期时间内卖才能算利润,每天只能卖一件商品,问利润最大值。

思路:用并查集+贪心的思路,先给商品从大到小排序,然后选择过期时间的根节点,再将根节点和根节点-1的时间merge,当根节点不为0,累计加上利润

最后求得最大值。因为过期时间具有传递性,你在第n天卖等价于第n-1天卖,很容易证得思路的正确性。

 

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cmath>
#define ll long long
using namespace std;
struct point 
{
    int x;
    int y;
}a[100010];
int fa[100100];
bool cmp(point a,point b)
{
    return a.x>b.x;
}
int get(int k)
{ 
    return fa[k]==k?k:fa[k]=get(fa[k]); 
}
void merge(int x,int y)
{
    fa[get(x)]=get(y); 
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=0;i<n;i++)
        {
            scanf("%d%d",&a[i].x,&a[i].y);
        }
        for(int i=1;i<=100000;i++)
        {
            fa[i]=i;
        }
        sort(a,a+n,cmp);
    /*    for(int i=0;i<n;i++)
        {
            printf("x:%d y:%d\n",a[i].x,a[i].y);
        }*/
        int sum=0;
        for(int i=0;i<n;i++)
        {
            int r=get(a[i].y);
        //    printf("r:%d\n",r);
            if(r!=0)
            {
                sum+=a[i].x;
                merge(r,r-1);
            }
        }
        printf("%d\n",sum);
    }
}

 

posted @ 2019-08-12 10:44  Ldler  Views(249)  Comments(0Edit  收藏  举报