會場安排問題
問題描述:假設要在足夠多的會場里安排一批活動,活動的開始時間和結束時間已知,並希望使用盡可能少的會場。設計一個有效的算法進行安排。
分析:這個問題實際上是著名的圖着色問題。若將每一個活動作為圖的一個頂點,不相容活動間用邊相連。使相鄰頂點着有不同顏色的最小着色數,就對應要找的最小會場數。 圖的最少着色問題,至今沒有有效的算法,但這個問題和圖的着色問題有不同,活動的時間區間之間的約束關系轉化得到的圖,屬於區間圖。我們可以用貪心策略來解決。
分析解答:
(1)n個活動開始和結束時間分別是s[i]和f[i],s[i]<f[i]。
(2)把n個活動時間看做直線上n個區間,把所有的s[i]和f[i]按大小排序,得到一個2n的有序數組。count用於統計會場數,遍歷數組,統計區間的最大的重疊數目。遇到s[i],一種活動進棧(相當於要安排一個會場),count數加1,比較當前的會場使用數是否是最大。遇到f[i],一種活動出棧(相當於一個會場用完,可以作為其他活動用),count數減1,直到把所有的活動都安排好,結束遍歷。
由於我們只要得到最少的會場數,遍歷數組時,遇到一個s[i],就把當前的count數加1,遇到對應的f[i]時,就把當前的count數減1,同時記錄每次循環時最大的count數,循環結束時,最大的count數就是我們需要的最少顏色數。這個算法的時間復雜度主要是由排序所影響,復雜度為O(N*logN)。
//TimePoint[]數組就是所有的s[i]和f[i]按大小排序的結果 int countUsing = 0; int maxCount = 0; for(int i = 0; i < 2*N; ++i) { if(TimePoint[i].type == "Begin") { ++ countUsing; if(countUsing > maxCount) maxCount = countUsing; } else -- countUsing; }