問題描述:
學校的小禮堂每天都會有許多活動,有時間這些活動的計劃時間會發生衝突,需要選擇出一些活動進行舉辦。小劉的工作就是安排學校小禮堂的活動,每個時間最多安排一個活動。現在小劉有一些活動計劃的時間表,他想盡可能的安排更多的活動,請問他該如何安排。
問題分析:
根據描述可知這是一道典型的貪心算法求最優解的問題。問題的求解在於選擇最優貪心策略。通過分析,可以得出以下幾種策略。
- 儘量選擇開始時間早的
一般情況下,開始的越早結束的也就越早,但是如果開始的早結束的晚,則最終的解只能是最優解的近似。
- 選擇會議時間佔用最少的
分析策略1,發現時間持續成了解題的關鍵,則我們策略2選擇會議時間最少的,時間最少,則在有限的時間可以安排更多的會議。但是這裏每場活動都有開始時間,倘若持續時間短的都排到了一天的末尾,則最終的解也只是問題最優解的近似。
- 選擇活動結束時間最早的
每次從待排活動中,選擇結束時間最早的,則有限的時間裏可以安排更多的活動。因此策略3可以作爲我們的貪心策略。
問題求解:
- 首先我們將待排活動按結束時間排序(遞增)
- 倘若結束時間相同,則按開始時間較晚的遞減排序
- 排序後待排活動中, 第一個活動一定是最先被安排的,因此我們需要按照第一個活動的結束時間,在接下來的活動中選擇結束時間最早的
- 選擇過程中,結束時間應該要大於或者等於下一場待排活動的開始時間,否則衝突
代碼示例:
#include<iostream>
#include<algorithm>
using namespace std;
struct Meet{
int beg;
int end;
int num;
};
bool cmp(Meet x, Meet y){
if(x.end == y.end)
return x.beg > y.beg;
return x.end < y.end;
}
int main(){
int n, count = 1, last;
cin >> n;
Meet met[n];
for(int i = 0; i < n; i++){
cin >> met[i].beg >> met[i].end;
met[i].num = i+1;
}
sort(met, met+n, cmp);
last = met[0].end;
cout << "beg:" << met[0].beg << " end:" << met[0].end << endl; //打印選中會議
for(int i = 1; i < n; i++){
if(met[i].beg >= last){
count++;
last = met[i].end;
cout << "beg:" << met[i].beg << " end:" << met[i].end << endl; //打印選中會議
}
}
cout << count;
return 0;
}