后悔贪心+P2949 [USACO09OPEN]Work Scheduling G
題意:
給你N個任務(wù),每個任務(wù) iii 都有截止日期DiD_{i}Di?和報酬PiP_{i}Pi?,每完成一個工作需要耗費1的單位時間,你需要使所得報酬最大并輸出。
題目描述
Farmer John has so very many jobs to do! In order to run the farm efficiently, he must make money on the jobs he does, each one of which takes just one time unit.
His work day starts at time 0 and has 1,000,000,000 time units (!). He currently can choose from any of N (1 <= N <= 100,000) jobs
conveniently numbered 1…N for work to do. It is possible but
extremely unlikely that he has time for all N jobs since he can only work on one job during any time unit and the deadlines tend to fall so that he can not perform all the tasks.
Job i has deadline D_i (1 <= D_i <= 1,000,000,000). If he finishes job i by then, he makes a profit of P_i (1 <= P_i <= 1,000,000,000).
What is the maximum total profit that FJ can earn from a given list of jobs and deadlines? The answer might not fit into a 32-bit integer.
輸入格式
-
Line 1: A single integer: N
-
Lines 2…N+1: Line i+1 contains two space-separated integers: D_i and P_i
輸出格式
- Line 1: A single number on a line by itself that is the maximum possible profit FJ can earn.
題意翻譯
約翰的工作日從 0時刻開始,有 10910^{9}109個單位時間。在任一單位時間,他都可以選擇編號1到N 的N(1<=N<=105)N(1<=N<=10^{5})N(1<=N<=105) 項工作中的任意一項工作來完成。工作 iii的截止時間是 Di(1<=Di<=109)D_{i}(1<=D_{i}<=10^{9})Di?(1<=Di?<=109) ,完成后獲利是 。在給定的工作利潤和截止時間下,求約翰能夠獲得的利潤最大為多少。
輸入
3
2 10
1 5
1 7
輸出
17
說明/提示
Complete job 3 (1,7) at time 1 and complete job 1 (2,10) at time 2 to maximize the earnings (7 + 10 -> 17).
分析:
1.先假設(shè)如果一個工作有時間去做,就先做了它,將各項工作按截止時間壓入一個小根堆。
2.當我們找到一個沒法做卻價值比當前堆頂高的工作時,我們就放棄那個最小的工作,用做它的時間去做這個價值更高的工作。用優(yōu)先隊列(小根堆)來維護隊首元素最小。
3.在判斷第 i 項工作做與不做時,若其截至?xí)r間符合條件,則將其與隊中報酬最小的元素比較,若第 i 項工作報酬較高(后悔),則 ans += a[i].p - q.top()。
復(fù)習(xí):
C++優(yōu)先隊列的基本使用方法
在優(yōu)先隊列中,優(yōu)先級高的元素先出隊列。
標準庫默認使用元素類型的<操作符來確定它們之間的優(yōu)先級關(guān)系。
- 優(yōu)先隊列的第一種用法,也是最常用的用法:
通過<操作符可知在整數(shù)中元素大的優(yōu)先級高。故隊列由大到小
- 第二種方法:
如果我們要把元素從小到大輸出怎么辦呢?
這時我們可以傳入一個比較函數(shù),使用functional.h函數(shù)對象作為比較函數(shù)。
其中
第二個參數(shù)為容器類型。
第二個參數(shù)為比較函數(shù)。
- 第三種方法:
自定義優(yōu)先級(直接在結(jié)構(gòu)體里寫,或者寫一個函數(shù))
AC代碼:
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<queue> using namespace std; typedef long long ll; const int M=1e5+10;struct node{int x,y;bool operator<(const node&a)const{return x<a.x;} }s[M]; priority_queue<int,vector<int>,greater<int> >q;//"> >"之前要有空格 int n; ll ans; int main(){cin>>n;ans=0;for(int i=1;i<=n;i++){cin>>s[i].x>>s[i].y;}sort(s+1,s+n+1);//先對時間排序for(int i=1;i<=n;i++){if(s[i].x<=q.size()){//當我們找到一個沒法做卻價值比當前堆頂高的工作時,我們就放棄那個最小的工作,用做它的時間去做這個價值更高的工作。if(s[i].y>q.top()){//用優(yōu)先隊列(小根堆)來維護隊首元素最小。ans=ans+s[i].y-q.top();q.pop();q.push(s[i].y);}}else{//可以做,就直接放進去q.push(s[i].y);ans+=s[i].y;}}cout<<ans<<endl;return 0; }總結(jié)
以上是生活随笔為你收集整理的后悔贪心+P2949 [USACO09OPEN]Work Scheduling G的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 毛霉菌是什么
- 下一篇: 二分+最大化最小值 River Hops