1. 程式人生 > >POJ 1456 (貪心+並查集)

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;
}