洛谷 P2278 [HNOI2003]操作系统(模拟,优先队列)
传送门
解题思路
首先是暴力做法:
从1开始枚举时间,每一次加一,判断有没有新的任务到达,然后挑出优先队列中的优先值最大的,执行一秒钟,在放回队列中。
显然是TLE的!
接着想一下优化:
找一找那里可以优化,发现只有时间!所以我们每一次取出队首(任务a)有两种情况——第一种是现在的时间+a的剩余完成工作需要的时间<下一个要到达的任务的时间,这时候最优策略一定是完成a这件工作;第二种是完不成工作,那就尽可能的多做,把a剩余需要的时间减去能做的时间,然后再重新放回队列中。
根据就是在新的任务没到达时,最优的总是队首,在新任务到达的那一刻,就不一定了,因为新元素可能比队首优先级高。
注意
- 结构体重载运算符的写法
- 比较能不能完成是小于等于而不是小于
AC代码
1 #include<iostream> 2 #include<algorithm> 3 #include<cmath> 4 #include<cstdio> 5 #include<cstring> 6 #include<queue> 7 using namespace std; 8 struct node{ 9 int num,t1,t2,d; 10 bool operator < (const node &x)const{ 11 return d==x.d?t1>x.t1:d<x.d; 12 } 13 }x; 14 priority_queue<node> q; 15 int nowt; 16 int main() 17 { 18 while(scanf("%d",&x.num)!=EOF){ 19 scanf("%d%d%d",&x.t1,&x.t2,&x.d); 20 if(q.empty()){ 21 q.push(x); 22 nowt=x.t1; 23 continue; 24 } 25 node f=q.top(); 26 while(nowt+f.t2<=x.t1){ 27 q.pop(); 28 nowt=nowt+f.t2; 29 printf("%d %d\n",f.num,nowt); 30 if(q.empty()) break; 31 f=q.top(); 32 } 33 if(q.empty()){ 34 nowt=x.t1; 35 q.push(x); 36 continue; 37 } 38 f.t2-=x.t1-nowt; 39 q.pop(); 40 q.push(f); 41 nowt=x.t1; 42 q.push(x); 43 } 44 while(!q.empty()){ 45 node f=q.top(); 46 q.pop(); 47 nowt=nowt+f.t2; 48 printf("%d %d\n",f.num,nowt); 49 } 50 return 0; 51 }
//HNOI2003 Day1t2