問題描述:
假設給定n個任務的集合T,每個任務i有啓動時間si和完成時間fi(si<fi)。任務i必須在si時刻啓動,並在fi時刻結束。每個任務都必須在一臺機器上執行,每臺機器同時只能執行一個任務。如果兩個任務i和j的實行時間不重疊,即fi<= sj或fi<=si,則稱這兩個任務不衝突。顯然,只有兩個任務不衝突時纔可以安排它們在同一臺機器上執行。
如何安排T中所有任務在不衝突的條件下在最少的機器上完成?
問題分析:
要求: 在最少的機器上安排完所有任務。
如何選擇貪心策略才能使問題的解爲最優解?顯然,開始時間最早的任務需要被先執行,但是最優解要求我們使用的機器最少,因此我們每次選擇時應儘量使用相同的機器。若已使用過的機器上現處於空閒狀態,則應將待執行任務放到該機器上執行。若無空閒機器,則再使用新機器。
代碼示例O(n^2):
#include<iostream>
#include<algorithm>
using namespace std;
struct thread{
int s;
int e;
}trd[1001];
bool cmp(thread x, thread y){
return x.s < y.s;
}
int main(){
int n;
cin >> n;
int k[n], ki = 0, rcd[n];
for(int i = 0; i < n; i++){
cin >> trd[i].s >> trd[i].e;
}
sort(trd, trd+n, cmp);
k[ki++] = trd[0].e;
rcd[0] = ki;
for(int i = 1, t = -1; i < n; i++){
for(int j = 0; j < ki; j++){
if(k[j] <= trd[i].s){
t = j;
break;
}
}
if(t != -1){
k[t] = trd[i].e;
rcd[i] = t+1;
} else {
k[ki++] = trd[i].e;
rcd[i] = ki;
}
}
for(int i = 0; i < n; i++){//輸出各任務在哪臺機器上運行
cout << rcd[i] << " ";
}
cout << "\n" << ki;
return 0;
}
最優解證明:
設在上述策略下最後一臺選擇的機器爲第k臺,i爲第一個在k上運行的任務。則1到k-1臺機器上都有任務正在運行,即i與前1到k-1個任務相沖突,並且1到k-1臺機器上運行的任務之間也是相互衝突的。因此任務集合T中至少有k個任務之間相互衝突,若使用k-1臺機器,則無法同時安排它們執行,因此最少使用k臺機器。
參考文獻《算法設計與應用》