任务(并查集,优先队列)

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

 

posted @ 2021-04-27 23:54  lipu123  阅读(70)  评论(0)    收藏  举报