51nod1163 最高的奖励(贪心+优先队列)

题目:
有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
 
题目思路:总奖励减去最小不能完成任务的奖励。建一个结构体数组储存时间e,奖励w。建两个队列,q1优先时间e(从小到大), q2优先奖励w(从小到大), 先把任务放进q1,再放入q2,用计数器算时间当时间大于任务量,则q2需要栈顶出栈(当前不能完成任务最小奖励)。
今天刚学优先队列,就用到了,有点菜,有了两三个小时才写出来,写得有点乱,不过很激动,刚学就用到了,而且纯是自己想,自己打的。
代码如下:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector> 
using namespace std;
struct node{
    long long e,w;
};
struct cmp1{
    bool operator ()(node &a,node &b)
    {
        return a.e>b.e;
    }
};
struct cmp2{
    bool operator ()(node &a,node &b)
    {
        return a.w>b.w;
    }
};
priority_queue<node,vector<node>,cmp1>q1;//优先时间(从小到大) 
priority_queue<node,vector<node>,cmp2>q2;//优先奖励(从小到大) 
int main()
{
    int n;
    while(cin>>n)
    {
        node a;
        long long ans=0,sum=0;
        for(int i=0;i<n;i++)
        {
            cin>>a.e>>a.w;
            ans+=a.w;//ans算出总奖励 
            q1.push(a);//放入优先时间队列 
        }
        int m=0;//计算当前时间是否可以做全部任务 
        for(int i=0;i<n;i++)
        {
            node t=q1.top();
            q1.pop();
            q2.push(t);//放入优先奖励队列 
            if(m>=t.e)//任务数大于当前最大时间,需要删除当前最小奖励的任务 
            {
                node p=q2.top();
                q2.pop();
                sum+=p.w;//sum计算不能做的最小奖励之和 
            }
            else
                m++;
        }
        cout<<ans-sum<<endl;
    }
    return 0;
}
 

猜你喜欢

转载自www.cnblogs.com/xiongtao/p/9273745.html