51nod 1163 最高的奖励

链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1163
基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题
 收藏
 关注
有N个任务,每个任务有一个最晚结束时间以及一个对应的奖励。在结束时间之前完成该任务,就可以获得对应的奖励。完成每一个任务所需的时间都是1个单位时间。有时候完成所有任务是不可能的,因为时间上可能会有冲突,这需要你来取舍。求能够获得的最高奖励。
Input
第1行:一个数N,表示任务的数量(2 <= N <= 50000)
第2 - N + 1行,每行2个数,中间用空格分隔,表示任务的最晚结束时间E[i]以及对应的奖励W[i]。(1 <= E[i] <= 10^9,1 <= W[i] <= 10^9)
Output
输出能够获得的最高奖励。
Input示例
7
4 20
2 60
4 70
3 40
1 30
4 50
6 10
Output示例
230


刚刚了解了一下优先队列,在这题上就用上了,一开始我也不会,看了博客... ,我们先用结构体排序,从结束时间小的
到结束时间大的,如果时间相同,就把奖励搞的在前面。
然后我们就可以以时间1为起点,end=1(所有活动的终止时间肯定>=1),把i=0的活动压入优先队列
然后从i=1循环,如果当前活动的结束时间大于end,那么end++,表示end+1这个时间做当前活动,并且把当前活动
压入队列,如果当前活动时间==end,
那么我们就要在在当前活动和队列顶的活动之间选择一个奖励更高的,如果当前比较的活动奖励高,就把队列顶的
元素pop掉,把当前活动压入,否则继续循环...
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define ll long long
ll n,m,k,t;
struct node{
    ll time,value;
}str[50005];
bool cmp(node s1,node s2)
{
    if(s1.time!=s2.time)
    return s1.time<s2.time;
    else
    return s1.value>s2.value;
}
priority_queue<ll,vector<ll>,greater<ll> >q; 
int main()
{
    scanf("%lld",&n);
    for(int i=0;i<n;i++)
    scanf("%lld%lld",&str[i].time,&str[i].value);
    sort(str,str+n,cmp);
    while(!q.empty())
    q.pop();
    q.push(str[0].value);
    ll end=1;
    for(int i=1;i<n;i++)
    {
        if(str[i].time>end)
        {
            q.push(str[i].value);
            end++;
        }
        else if(str[i].time==end)
        {
            if(str[i].value>q.top())
            {
                q.pop();
                q.push(str[i].value);
            }
        }
    }
    long long ans=0;
    while(!q.empty())
    {
        ans+=q.top();
        q.pop();
    }
    printf("%lld
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/6262369sss/p/9119387.html