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

题目:

原题如下:

有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

思路:

如果只用普通的贪心是可以的,因为这个题他有个隐藏的条件,那就是可以提前用。
如果题目是说这个题只能在这一刻做,那么就直接贪心,但是这个可以提前。 
也就是说对于t时刻时,我们一共最多能完成t-1个题,但是这t-1个题,只要是在规定时间内即可。
我们遍历所有的题目,对于当前题目,得到他是最晚运行时间z。
如果队列(我们做了的题目)数量小于z,也就是说我们这个z这个题目可以做,直接做即可。
如果数量大于等于z了,我们这道题做还是不做,要看看里面还有没有更小的,把获得价值最小的题目取出来,把这个放进去即可。
对于这种最晚运行,这种要求的题目,用到了优先队列。


原文:https://blog.csdn.net/little_boy_z/article/details/78501710?utm_source=copy 
 

C++队列Queue类成员函数有:

back() 返回最后一个元素

empty() 如果队列空则返回真

front() 返回第一个元素

pop() 删除第一个元素

push() 在末尾加入一个元素

size() 返回队列中元素的个数

AC代码:

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
struct node
{
	int time;
	int val;
}a[50010];
bool cmp(node t1,node t2)  
{
	if(t1.time==t2.time)
	return t1.val>t2.val;
	else return t1.time<t2.time;
}

int main()
{
	int i,j,n;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		scanf("%d%d",&a[i].time,&a[i].val);
	}	
	sort(a,a+n,cmp);
	long long int ans=0;  //ans最后加起来有可能超过int的
	priority_queue<int,vector<int>,greater<int> > pq;
	for(int i=0;i<n;i++)
	{
		int k=a[i].val;
		if(a[i].time>pq.size())//要插入的截止时间大于已加入任务用的总时间 
		{
			ans+=k;
			pq.push(k); 
		}
		else     
		{
			ans+=k;
			pq.push(k);
			int t=pq.top(); //替换掉栈顶那个价值最小的 
			pq.pop();
			ans-=t;
		}
	}
	cout<<ans<<endl;
	return 0;
 } 

猜你喜欢

转载自blog.csdn.net/zvenWang/article/details/83115911
今日推荐