您的位置:首页 > 运维架构

【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

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: