POJ 1456 (贪心+并查集)

题意:买卖N件东西,每件东西都有个截止时间,在截止时间之前买都可以,而每个单位时间只能买一件。问最大获利。

思路:一开始我想错了,以为每个东西只能在特定的时间买,结果是截止时间前买都可以,所以先对所有数据按利润由大到小排序,然后用并查集来找截止时间的更新,也就是如果某个点的截止时间大于0,那么截止时间减一(其他相同的截止时间要提前一天进行),如果截止时间小于0,也就代表这个东西买不了了(之前相同的截止时间已经有更大的利润了)。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int maxn=10005;
const double eps=1e-8;
const double PI = acos(-1.0);
ll gcd(ll a,ll b)
{
    return b==0?a:gcd(b,a%b);
}
struct node
{
    int p,t;
    bool operator< (node b)
    {
        return p>b.p;
    }
};
int pre[maxn];
int find(int x)
{
    if(x==pre[x])
    {
        return x;
    }
    else
    {
        int root=find(pre[x]);
        return pre[x]=root;
    }
}
int main()
{
    int n;
    while(cin>>n)
    {
        node a[maxn];
        for(int i=0; i<maxn; i++)
        {
            pre[i]=i;
        }
        for(int i=1; i<=n; i++)
        {
            cin>>a[i].p>>a[i].t;
        }
        sort(a+1,a+n+1);
        int ans=0;
        for(int i=1; i<=n; i++)
        {
            int t=find(a[i].t);
            if(t>0)
            {
                ans+=a[i].p;
                pre[t]=t-1;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Dilly__dally/article/details/84573591