51nod 1163 最高的獎勵

2021-08-21 18:22:14 字數 1648 閱讀 8512

1163 最高的獎勵

基準時間限制:1 秒 空間限制:131072 kb 分值: 20 難度:3級演算法題

有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
思路:優先佇列/貪心+並查集

一:優先佇列-由後向前:先將任務按照完成時間由大到小排序,由最晚完成時間開始安排任務,將所有可以安排的任務放入優先佇列q(價值大的優先),每次安排佇列q.top()即可,由於e[i]<=10^9,可能會超時,因此當佇列q中為空時,可將時間直接跳到下一任務上。

二:優先佇列-由前向後:將任務按照完成時間由小到大排序,由最早完成時間開始安排任務,將任務放入優先佇列q(價值小的優先)中,若當前任務的完成時間大於佇列中的任務個數,則將最小價值的出隊即可。

三:貪心+並查集:將任務按照價值由大到小排序,先安排價值大的任務,按照貪心策略,應該將其安排在它最晚時間點上,對於已經安排的時間點,用並查集記錄其前面最近的未安排的時間點,由於e[i]<=10^9太大,而n<=50000,因此對於e[i]>n的任務說明它安排在任意時間點上,因此可以將其修改為n。這樣每次查詢e[i]點所能夠安排的最大時間點,若其為0說明沒有時間點可以安排,否則修改其記錄值。

code 1:

//優先佇列-由後到前 

#include#include#includeusing namespace std;

typedef long long ll;

struct node

};const int max_n=100005;

int n;

node a[max_n];

int main()

};const int max_n=50005;

int n;

int id[max_n];

node a[max_n];

int find(int x);

int main()

id[n]=n;

sort(a,a+n);

for(int i=0;i

if(find(id[a[i].time])) id[find(id[a[i].time])]-=1;

else a[i].w=0;

ll ans=0;

for(int i=0;i

ans+=a[i].w;

cout<

} return 0;

}int find(int x)

51Nod 1163 最高的獎勵

acm模版 這是一道十分不錯的貪心問題,有o nlogn 和o n n 解法。oneo nlogn 演算法 將最晚結束時間公升序排序,第n個任務最晚時間如果大於已經消耗的時間,則可以算入總和,若不大於可以嘗試替換掉已經算入總和中的最小獎勵的任務,條件是這件任務的獎勵要大於要替換掉的任務的獎勵。使用優...

51NOD 1163 最高的獎勵

這個題 自己想了想 mmp 感覺一做貪心題只會用 sort 忽略了 優先佇列 這題搜了題解後 大概明白了 就是建立乙個最小堆 把cost 壓入最小堆 如果當前時間 q.size 說明可以直接加 如果小於等於 就要把cost 壓入後 取乙個最小的出來 挺好的乙個題 include using name...

最高的獎勵 51Nod 1163

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