1. 程式人生 > >BZOJ 1572 [Usaco2009 Open]工作安排Job:貪心 + 優先隊列【先放再更新】

BZOJ 1572 [Usaco2009 Open]工作安排Job:貪心 + 優先隊列【先放再更新】

blog struct else ref font string work usaco 貪心

題目鏈接:http://www.lydsy.com/JudgeOnline/problem.php?id=1572

題意:

  有n個工作,每個工作有一個截止日期dead[i]和收益pay[i]。

  完成一項工作需要花費1的時間。

  問你最大收益。

題解:

  貪心。

  先將n個工作按dead從小到大排序。

  開一個優先隊列q(升序),保存當前選了的工作的pay。

  枚舉每個工作i:

    (1)如果當前q中的工作數 < pay[i],說明在pay[i]及之前的時間還有沒用的。所以直接選這個工作。

    (2)如果當前q中的工作數 = pay[i],說明沒有空閑時間了。所以如果q中最小的收益比pay[i]還小,則用當前工作替換掉。

  最後q中剩下的就是最終要選的工作。

AC Code:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <algorithm>
 5 #include <queue>
 6 #define MAX_N 100005
 7 
 8 using namespace std;
 9 
10 struct Work
11 {
12     long long dead;
13     long long pay;
14     Work(long
long _dead,long long _pay) 15 { 16 dead=_dead; 17 pay=_pay; 18 } 19 Work(){} 20 friend bool operator < (const Work &a,const Work &b) 21 { 22 return a.dead<b.dead; 23 } 24 }; 25 26 int n; 27 long long ans=0; 28 Work work[MAX_N]; 29 priority_queue<long
long,vector<long long>,greater<long long> > q; 30 31 void read() 32 { 33 cin>>n; 34 for(int i=0;i<n;i++) 35 { 36 cin>>work[i].dead>>work[i].pay; 37 } 38 } 39 40 void solve() 41 { 42 sort(work,work+n); 43 for(int i=0;i<n;i++) 44 { 45 if(q.size()<work[i].dead) q.push(work[i].pay); 46 else if(q.top()<work[i].pay) 47 { 48 q.pop(); 49 q.push(work[i].pay); 50 } 51 } 52 while(!q.empty()) 53 { 54 ans+=q.top(); 55 q.pop(); 56 } 57 } 58 59 void print() 60 { 61 cout<<ans<<endl; 62 } 63 64 int main() 65 { 66 read(); 67 solve(); 68 print(); 69 }

BZOJ 1572 [Usaco2009 Open]工作安排Job:貪心 + 優先隊列【先放再更新】