题意:买卖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;
}