51Nod 最高的奖励【贪心】【优先队列】(已更正错误)

N 个任务,每个任务有一个最晚结束时间以及一个对应的奖励。在结束时间之前完成该任务,就可以获得对应的奖励。完成每一个任务所需的时间都是 1 个单位时间。有时候完成所有任务是不可能的,因为时间上可能会有冲突,这需要你来取舍。求能够获得的最高奖励。

这道题也是一道比较简单的贪心了。

因为要贪心嘛,所以一共有 N 天,那么我们就要考虑最后完成 N 个任务。

既然想到了这一点,那么我们怎样才能保证在第 i 天的时候完成了第 i 个奖励最高的任务呢

我们考虑一下倒推:我们从第 N 天往前推,在第 i 天的时候把要在 j i j 天前完成的任务放进优先队列,然后对于每一天,若如果优先队列不为空,我们就取出优先队列中奖励最大的那一个即可。

参考代码:

#include <queue>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define SG string
#define DB double
#define LL long long
using namespace std;
const LL Max=5e4+5;
struct Node{
    int Day,Val;
    bool operator < (const Node &A) const{
        return Val<A.Val;
    }
}G[Max];
LL N,Cur,Ans;
priority_queue<Node>PQ;
inline LL Read(){
    LL X=0;char CH=getchar();bool F=0;
    while(CH>'9'||CH<'0'){if(CH=='-')F=1;CH=getchar();}
    while(CH>='0'&&CH<='9'){X=(X<<1)+(X<<3)+CH-'0';CH=getchar();}
    return F?-X:X;
}
inline void Write(LL X){
    if(X<0)X=-X,putchar('-');
    if(X>9)Write(X/10);
    putchar(X%10+48);
}
bool Cmp(Node P,Node Q){
    return P.Day<Q.Day;
}
int main(){
    LL I,J,K;
    N=Read();Cur=N;
    for(I=1;I<=N;I++){
        G[I].Day=Read();G[I].Val=Read();
    }
    sort(G+1,G+1+N,Cmp);
    for(I=N;I;I--){
        while(true){
            if(G[Cur].Day<I){
                break;
            } else{
                PQ.push(G[Cur]);Cur--;
            }
        }
        if(PQ.size()!=0){
            Node Tmp=PQ.top();PQ.pop();
            Ans+=Tmp.Val;
        }
    }
    Write(Ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yanzhenhuai/article/details/81108324
今日推荐