BZOJ 1572 [Usaco2009 Open]工作安排Job:贪心 + 优先队列【先放再更新】

题目链接: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 }

 

posted @ 2017-10-03 14:33  Leohh  阅读(174)  评论(0编辑  收藏  举报