家庭作业
https://loj.ac/problem/10008
题目描述
有\(n\)个任务,每个任务都有完成时间和完成奖励,求最大的完成奖励。
思路
这道题的贪心策略与智力大冲浪相类似,就不再赘述了。主要讲优化。智力大冲浪这道题的数据比较水,\(Ο(n^2)\)的复杂度都能过。但这里显然过不去,那么就考虑优化。首先扫一遍任务是必需花费,不可减少,就考虑从寻找最近可安排时刻进行优化。我们可以用并查集来维护无效区间,每次只需要往前跳就行了。当然用链表维护也可以。
代码
#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
struct aa
{
int d,v;
bool operator < (const aa &x)const
{
return v<x.v;
}
}a;
priority_queue<aa>q;
int fa[710000];
bool cmp(aa x,aa y)
{
return x.v>y.v;
}
int read()
{
char ch=getchar();
int ret=0,w=1;
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();}
return ret*w;
}
int find(int x)
{
return fa[x]==x?x:fa[x]=find(fa[x]);
}
int main()
{
int n,maxx=0;
n=read();
for(int i=1;i<=n;++i)
{
a.d=read(),a.v=read();
q.push(a);
maxx=max(a.d,maxx);
}
for(int i=1;i<=maxx;i++)
fa[i]=i;
int ans=0;
for(int i=1;i<=n;++i)
{
int flag=0;
a=q.top();q.pop();
if(find(a.d))
{
ans+=a.v;
fa[fa[a.d]]=find(fa[fa[a.d]]-1);
}
}
printf("%d",ans);
return 0;
}