【bzoj1572/Usaco2009 Open】工作安排Job——优先队列
2017-09-13 14:20
190 查看
分析:因为每个事件的代价(也就是时间)是一样的,因此很容易想到应该是贪心。但是这里我们换一种思路来做:不是从大往小选,而是从前往后选,当时间不够用时就把利润最小的舍弃掉加入当前事件的,所以这里我们要先把事件按照第一维截止时间从小到大,第二维利润从小到大排序,然后枚举1~n,开一个利润从小到大的优先队列。每次枚举到事件i,若此时优先队列的size比当前事件的截止时间小,说明此时队列里的都可以选(因为事件已经按照截止时间排序),直接入队;否则,删除队首(也就是当前利润最小的事件),然后入队。枚举完统计一下还在队列里的事件利润即可。
代码:
#include<cstdio> #include<cstring> #include<queue> #include<algorithm> const int N=1e5+10; struct node{ int w; bool operator <(const node &p)const {return p.w<w;} }; struct point{ int d,p; }e ; int read(){ int ans=0,f=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();} return ans*f; } bool cmp(point a,point b){return a.d<b.d||(a.d==b.d&&a.p<b.p);} std::priority_queue<node>q; int main(){ long long ans=0; int n=read(); for(int i=1;i<=n;i++) e[i].d=read(),e[i].p=read(); std::sort(e+1,e+1+n,cmp); for(int i=1;i<=n;i++){ if(q.size()<e[i].d)q.push((node){e[i].p}); else { q.pop();q.push((node){e[i].p}); } } while(!q.empty()){ ans+=q.top().w;q.pop(); } printf("%lld",ans); return 0; }Usaco2009
相关文章推荐
- 【BZOJ 1572】 1572: [Usaco2009 Open]工作安排Job(贪心+优先队列)
- [bzoj1572]: [Usaco2009 Open]工作安排Job
- BZOJ1572: [Usaco2009 Open]工作安排Job
- BZOJ 1572[Usaco2009 Open]工作安排Job
- 【bzoj1572】[Usaco2009 Open]工作安排Job 贪心+堆
- BZOJ1572 [Usaco2009 Open]工作安排Job
- BZOJ1572: [Usaco2009 Open]工作安排Job 贪心
- bzoj1572 [Usaco2009 Open]工作安排Job
- bzoj 1572: [Usaco2009 Open]工作安排Job【贪心+堆】
- bzoj 1572: [Usaco2009 Open]工作安排Job
- bzoj1572[Usaco2009 Open]工作安排Job 堆
- [bzoj1572][Usaco2009 Open]工作安排Job_贪心_堆
- 【BZOJ】1572: [Usaco2009 Open]工作安排Job
- bzoj1572 [Usaco2009 Open]工作安排Job(贪心)
- bzoj1572 [Usaco2009 Open]工作安排Job
- BZOJ 1572: [Usaco2009 Open]工作安排Job( 贪心 )
- BZOJ1572 [Usaco2009 Open]工作安排Job
- Bzoj1572 [Usaco2009 Open]工作安排Job
- [BZOJ1572] [Usaco2009 Open]工作安排Job(贪心 + 堆)
- 【BZOJ1572】【usaco 2009 open】工作安排job