任务(并查集,优先队列)
有N个任务,每个任务有一个最晚结束时间以及一个对应的奖励。在结束时间之前完成该任务,就可以获得对应的奖励。完成每一个任务所需的时间都是1个单位时间。有时候完成所有任务是不可能的,因为时间上可能会有冲突,这需要你来取舍。求能够获得的最高奖励。
输入
第1行:一个数N,表示任务的数量(2 <= N <= 50000) 第2 ~ N+1行,每行2个数,中间用空格分隔,表示任务的最晚结束时间E[i]以及对应的奖励W[i]。(1 <= E[i] <= 10^9,1 <= W[i] <= 10^9)
输出
输出能够获得的最高奖励。
输入样例
7
4 20
2 60
4 70
3 40
1 30
4 50
6 10
输出样例
230
1.并查集
#include<iostream> #include<algorithm> #include<cstring> typedef long long ll; using namespace std; const int maxn=1e5+100; int pre[maxn]; struct node{ ll w; ll t; }a[maxn]; bool cmp(node x,node y){ return x.w>y.w; } int find(int x){ if(pre[x]==-1){ return x; } else{ return pre[x]=find(pre[x]); } } int main(){ int n; cin>>n; for(int i=1;i<=n;i++){ scanf("%d%d",&a[i].t,&a[i].w); } memset(pre,-1,sizeof(pre)); sort(a+1,a+n+1,cmp); ll ans=0; for(int i=1;i<=n;i++){ int p=find(a[i].t); if(p>0){ ans+=a[i].w; pre[p]=p-1; } } cout<<ans<<endl; }
2.优先队列
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 50000+10; struct node { int l,cost; bool operator <(const node & a)const{ return l < a.l; } }s[maxn]; int main () { int n; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d%d",&s[i].l,&s[i].cost); sort(s,s+n); priority_queue<int,vector<int>,greater<int> > Q; ll res = 0; for(int i=0;i<n;i++) { if(s[i].l > Q.size()){ res += s[i].cost; Q.push(s[i].cost); } else { res += s[i].cost; Q.push(s[i].cost); int t = Q.top(); Q.pop(); res -= t; } } printf("%lld\n",res); }