洛谷 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

posted @ 2019-12-26 19:49  尹昱钦  阅读(150)  评论(0编辑  收藏  举报