1. 程式人生 > >【51Nod - 1163 】【最高的獎勵】

【51Nod - 1163 】【最高的獎勵】

題目:

有N個任務,每個任務有一個最晚結束時間以及一個對應的獎勵。在結束時間之前完成該任務,就可以獲得對應的獎勵。完成每一個任務所需的時間都是1個單位時間。有時候完成所有任務是不可能的,因為時間上可能會有衝突,這需要你來取捨。求能夠獲得的最高獎勵。

Input

第1行:一個數N,表示任務的數量(2 <= N <= 50000) 
第2 - N + 1行,每行2個數,中間用空格分隔,表示任務的最晚結束時間Eii以及對應的獎勵Wii。(1 <= Eii <= 10^9,1 <= Wii <= 10^9)

Output

輸出能夠獲得的最高獎勵。

Sample Input

7
4 20
2 60
4 70
3 40
1 30
4 50
6 10

Sample Output

230

解題報告:一上來就會被定性思維困住,就會打算從第一天的開始往後尋找,其實是走進了思維坑點,沒有明確就是之後日期完成的任務其實也可以在deadline之前完成。所以轉變一下思維,從後往前推,將截止日期前能完成的可獲得最大金額的任務完成。具體實現就是用優先佇列,其中是按照時間的倒序進行的。

ac程式碼:

#include<bits/stdc++.h>
#include<vector>
#include<queue>
using namespace std;
const int maxn =50000+100;
vector <int >a[maxn];
priority_queue<int > q;
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		for(int i=1;i<=n;i++)
		{
			int x,y;
			scanf("%d%d",&x,&y);
			if(x>n) x=n;
			a[x].push_back(y);
		}
		long long ans=0;
		for(int i=n;i>=1;i--)
		{
			for(int j=0;j<a[i].size();j++)
				q.push(a[i][j]);
			if(!q.empty())	
			{
				ans+=q.top();
				q.pop();
			}
		}
		printf("%lld\n",ans);
	}
}