1. 程式人生 > >【bzoj1572/Usaco2009 Open】工作安排Job——優先隊列

【bzoj1572/Usaco2009 Open】工作安排Job——優先隊列

代碼 com online job line mil 排序 技術分享 zoj

題目鏈接

分析:因為每個事件的代價(也就是時間)是一樣的,因此很容易想到應該是貪心。但是這裏我們換一種思路來做:不是從大往小選,而是從前往後選,當時間不夠用時就把利潤最小的舍棄掉加入當前事件的,所以這裏我們要先把事件按照第一維截止時間從小到大,第二維利潤從小到大排序,然後枚舉1~n,開一個利潤從小到大的優先隊列。每次枚舉到事件i,若此時優先隊列的size比當前事件的截止時間小,說明此時隊列裏的都可以選(因為事件已經按照截止時間排序),直接入隊;否則,刪除隊首(也就是當前利潤最小的事件),然後入隊。枚舉完統計一下還在隊列裏的事件利潤即可。

代碼:

技術分享
 1 #include<cstdio>
 2
#include<cstring> 3 #include<queue> 4 #include<algorithm> 5 const int N=1e5+10; 6 struct node{ 7 int w; 8 bool operator <(const node &p)const {return p.w<w;} 9 }; 10 struct point{ 11 int d,p; 12 }e[N]; 13 int read(){ 14 int ans=0,f=1;char
c=getchar(); 15 while(c<0||c>9){if(c==-)f=-1;c=getchar();} 16 while(c>=0&&c<=9){ans=ans*10+c-48;c=getchar();} 17 return ans*f; 18 } 19 bool cmp(point a,point b){return a.d<b.d||(a.d==b.d&&a.p<b.p);} 20 std::priority_queue<node>q; 21 int
main(){ 22 long long ans=0; 23 int n=read(); 24 for(int i=1;i<=n;i++) 25 e[i].d=read(),e[i].p=read(); 26 std::sort(e+1,e+1+n,cmp); 27 for(int i=1;i<=n;i++){ 28 if(q.size()<e[i].d)q.push((node){e[i].p}); 29 else { 30 q.pop();q.push((node){e[i].p}); 31 } 32 } 33 while(!q.empty()){ 34 ans+=q.top().w;q.pop(); 35 } 36 printf("%lld",ans); 37 return 0; 38 }
Usaco2009

【bzoj1572/Usaco2009 Open】工作安排Job——優先隊列