貪心-會議安排問題

問題描述:

學校的小禮堂每天都會有許多活動,有時間這些活動的計劃時間會發生衝突,需要選擇出一些活動進行舉辦。小劉的工作就是安排學校小禮堂的活動,每個時間最多安排一個活動。現在小劉有一些活動計劃的時間表,他想盡可能的安排更多的活動,請問他該如何安排。

問題分析:

根據描述可知這是一道典型的貪心算法求最優解的問題。問題的求解在於選擇最優貪心策略。通過分析,可以得出以下幾種策略。

  1. 儘量選擇開始時間早的

一般情況下,開始的越早結束的也就越早,但是如果開始的早結束的晚,則最終的解只能是最優解的近似。

  1. 選擇會議時間佔用最少的

分析策略1,發現時間持續成了解題的關鍵,則我們策略2選擇會議時間最少的,時間最少,則在有限的時間可以安排更多的會議。但是這裏每場活動都有開始時間,倘若持續時間短的都排到了一天的末尾,則最終的解也只是問題最優解的近似。

  1. 選擇活動結束時間最早的

每次從待排活動中,選擇結束時間最早的,則有限的時間裏可以安排更多的活動。因此策略3可以作爲我們的貪心策略。

問題求解:
  1. 首先我們將待排活動按結束時間排序(遞增)
  2. 倘若結束時間相同,則按開始時間較晚的遞減排序
  3. 排序後待排活動中, 第一個活動一定是最先被安排的,因此我們需要按照第一個活動的結束時間,在接下來的活動中選擇結束時間最早的
  4. 選擇過程中,結束時間應該要大於或者等於下一場待排活動的開始時間,否則衝突
代碼示例:
#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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章