SOJ 1717 Computer (單機任務調度)

1、題目描述ios

Constraints :Time Limit: 2 secs, Memory Limit: 32 MB算法

Description:dom

  We often hear that computer is a magic, a great invention, or even a marvel. But actually computer is just a tool people use everyday. It is a machine that can help people to process many jobs effectively. Moreover, without computer, you can not play ICPC. So, guys, let’s study some stuff about computer here.
  One computer has one CPU (Central Processing Unit). CPU can be idle or processing one job at any time. Jobs come randomly and are stored in the memory until finished. CPU will process jobs according to some strategies. The processing job can be interrupted and saved back so that CPU can be available for other jobs. 
  Each job has a release time and a processing time. Assume that we know the schedule of all jobs, please generate a program to minimize the sum of completion times of all jobs using a strategy which assigns and interrupts jobs properly.
  For example, suppose there are two jobs to be completed. Job 1 is released at time 1 and needs 4 time units to process. Job 2’s release time and processing time is 3 and 1. Figures below show three solutions:ide


  Figure 1 shows a solution with the total complete time 4 + 6 = 10, and the result of Figure 2 and 3 are both 5 + 6 = 11. In fact, Figure 1 shows the optimal solution 
Please note that all of the jobs will be released, interrupted and assigned in integer time unit.spa

Input:設計

  Input may consist of multiple test cases.
  Every test case begins with a line that contains one integer n (1<= n <= 50000) denoting the number of jobs. Each of the following n lines contains 2 integers: ri and pi, (1 <= ri <= 10^9, 1 <= pi <= 10000) denoting the release time and processing time of job i.
  Input is terminated by EOF.code

Output:blog

  For every test case, print one line with an integer denoting the minimum sum of completion times.three

Sample Input隊列

  2
  1 4
  3 1
Sample Output

  10

2、問題解決

  一、題意:單機任務調度,模擬CPU工做方式,CPU每一個時刻只能處理一個任務,給出每一個任務的release時間和process時間,設計調度算法,使全部任務完成時間總和最小。

  二、思路:貪心思想,每次處理process時間最短的任務。

  具體步驟:用循環模擬CPU,每一個循環表示一個CPU時間。全局維護一個待處理的最小任務優先隊列que,即剩餘process時間短的任務優先。每次循環中:(1)取出que中top元素,將其剩餘process時間減1,即CPU此時刻處理該任務,減到0則記錄該任務完成時間;(2)將該時間刻release的任務加入等候隊列que中。

  三、代碼:基於上面的思路,能夠寫出下面的代碼。

 1 // Problem#: 1717
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <queue>
 5 #include <algorithm>
 6 using namespace std;
 7 const int MAX = 50000;
 8 struct Job
 9 {
10     int r,p;
11     bool operator < (const Job &job) const {
12         if(r == job.r) return p < job.p;
13         else return r < job.r;
14     }
15 };
16 Job jobs[MAX];
17 
18 int main() {
19     int n;
20     while(scanf("%d",&n) != EOF) {
21         for(int i = 0; i < n; ++i) {
22             scanf("%d%d", &jobs[i].r, &jobs[i].p);   
23         }
24         sort(jobs,jobs+n);
25 
26         priority_queue<int,vector<int>,greater<int> > que;
27         long long ans = 0;
28         int cnt = 0, cur = 1, tmp;
29 
30         que.push(jobs[0].p);
31         for(long long i = jobs[0].r; ;++i) {
32             tmp = que.top(); que.pop();
33             if (tmp-1 == 0) {
34                 ans = ans+i;
35                 cnt += 1;
36                 if(cnt == n) break;
37             }
38             else que.push(tmp-1);
39             while(cur < n && jobs[cur].r <= i) {
40                 que.push(jobs[cur++].p);
41             }
42         }
43         printf("%lld\n",ans);       
44     }
45     return 0;
46 }                                 
暴力代碼

   四、進一步分析:雖然思路對了,但上面代碼明顯會超時。

  這時考慮加快cpu工做速度,即不是模擬CPU每一個時刻處理的任務,而是考慮每一個任務可否一次性完成。大概思路是這樣,取出que中最小任務時間,判斷在下一個任務release時刻(距離上一任務process時刻會有一段時間間隔),該任務可否完成,若能完成,就能夠縮短期間隔,繼續判斷下一任務;若不能完成,則將該任務process時間減去時間間隔,從新加入que,並將下一任務加入que。

代碼以下:

 1 // Problem#: 1717
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <queue>
 5 #include <algorithm>
 6 using namespace std;
 7 const int MAX = 50000;
 8 struct Job
 9 {
10     int r,p;
11     bool operator < (const Job &job) const {
12         if(r == job.r) return p < job.p;
13         else return r < job.r;
14     }
15 };
16 Job jobs[MAX];
17 
18 int main() {
19     int n;
20     while(scanf("%d",&n) != EOF) {
21         for(int i = 0; i < n; ++i) {
22             scanf("%d%d", &jobs[i].r, &jobs[i].p);   
23         }
24         sort(jobs,jobs+n);
25 
26         priority_queue<int,vector<int>,greater<int> > que;
27         long long ans = 0;
28         int i = 1, cnt = 0, cur, tmp;
29         int pre = jobs[0].r;  //前一任務處理時刻
30         int cur_time = jobs[0].r;   //當前時刻
31 
32         que.push(jobs[0].p);
33         while(true) {
34             cur = que.top(); que.pop();
35             if (i >= n) {
36                 cur_time += cur;
37                 ans += cur_time;
38                 cnt += 1;
39                 if (cnt == n) break;
40                 continue;
41             }
42             tmp = jobs[i].r - pre;
43             if (cur <= tmp) {
44                 cur_time += cur; 
45                 ans += cur_time;
46                 cnt += 1;
47                 pre = cur_time;
48                 if (cnt == n) break;
49                 if (!que.empty()) continue;   //時間間隔縮短,可否繼續處理que中剩餘任務
50             }else {
51                 que.push(cur-tmp);
52                 cur_time = jobs[i].r;
53             }
54             pre = jobs[i].r;
55             cur_time = pre;
56             while(i < n && jobs[i].r == pre)
57                 que.push(jobs[i++].p);
58         }
59 
60         printf("%lld\n",ans);       
61     }
62     return 0;
63 }                                     
View Code

結果超出個人想象,折磨了2個小時,感受智商遠遠不夠用啊!

相關文章
相關標籤/搜索