题目:
有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,q2,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; }