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

Leohh發表於2017-10-03

題目連結: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 }

 

相關文章