1. 程式人生 > >51nod 1163 最高的獎勵(優先佇列+貪心)

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;
 }