有若干個活動,第i個開始時間和結束時間是[si,fi),活動之間不能交疊,要把活動都安排完,至少需要幾個教室?
分析:能否按照之一問題的解法,每個教室安排盡可能多的活動,即按結束時間排序,再貪心選擇不衝突的活動,安排乙個教室之後,剩餘的活動再分配乙個教室,繼續貪心選擇……
反例: a:[1,2) b:[1,4) c:[5,6) d:[3,7)
已經按結束時間排好順序,我們會選擇
教室1: a c
教室2: b
教室3: d
需要3個教室。
但是如果換一種安排方法,我們可以安排ad在乙個教室,而bc在另外乙個教室,兩個教室就夠了。
所以之前的貪心策略解決不了這個問題。
怎麼辦?之前的策略是用乙個教室找所有它能安排下的活動,即用教室找活動,我們能不能用活動找教室呢?
策略: 按照開始時間排序優先安排活動,如果衝突,則加乙個教室。
簡單地理解一下,策略是這樣,我們把活動按照開始時間有小到大的順序排序。假設目前已經分配了k個教室(顯然k初始等於0),對於當前這個活動,
(1) 如果它能安排在k個教室裡的某乙個,則把它安排在其中的任何乙個教室裡,k不變。
(2) 否則它和每個教室裡的活動都衝突,則增加乙個教室,安排這個活動。
這個策略是最優麼?
我們想像一下k增加1的過程: 因為我們是按照開始時間排序的,意味著當前考慮的這個活動開始的時候,k個教室裡都有活動沒結束(因為如果有乙個教室的活動結束了,我們就可以安排這個活動進入那個教室而不衝突,從而不用增加k)。這就意味著在這個活動開始的時間點,算上目前考慮的這個活動,有(k + 1)個活動正在進行,同一時刻有(k + 1)個活動在進行,無論我們如何安排教室,都至少需要(k + 1)個教室。因為每個教室裡不能同時進行兩個活動。而我們的策略恰好需要(k + 1)個教室,所以是最優的。
這個策略也告訴我們,如果從時間軸上「巨集觀」考慮這個問題。考慮每個時間點同時進行的活動個數,作為這個時間點的厚度(把活動開始和結束時間想像成線段,那麼每個時間點有多少條線段覆蓋它,可以簡單理解為「厚度」),我們至少需要最大厚度那麼多個教室——因為那時恰好有最大厚度那麼多個活動同時進行,而我們這個貪心策略恰好給了我們乙個用最大厚度那麼多個教室安排全部活動的乙個方案。
如果只需要教室的個數,我們可以把所有開始時間和結束時間排序,遇到開始時間就把厚度加1,遇到結束時間就把厚度減1,顯然最初始和最後結束時的厚度是0,在一系列厚度變化的過程中,峰值(最大值)就是最多同時進行的活動數,也是我們至少需要的教室數。
最後,我們來提供輸入輸出資料,由你來寫一段程式,實現這個演算法,只有寫出了正確的程式,才能繼續後面的課程。
輸入
第一行乙個正整數n (n <= 10000)代表活動的個數。第二行到第(n + 1)行包含n個開始時間和結束時間。
開始時間嚴格小於結束時間,並且時間都是非負整數,小於1000000000
輸出
一行包含乙個整數表示最少教室的個數。
輸入示例
31 23 4
2 9
輸出示例
2
**如下:
#include#include#define inf -1000000010
using namespace std;
struct stu;
stu cas[10100*2];
int cmp(stu a,stu b)
printf("%d\n",max);
} return 0;
}
51Nod 排隊接水 貪心
n n 個人一起排隊接水,第 i role presentation i i個人需要b i b i 的時間來接水。1 n 1000 1 n 1000 0 b i 1000 0 b i 1000 同時只能有乙個人接水,正在接水的人和沒有接水的人都需要等待。完成接水的人會立刻消失,不會繼續等待。你可以決...
51nod 活動安排問題 (貪心)
有若干個活動,第i個開始時間和結束時間是 si,fi 只有乙個教室,活動之間不能交疊,求最多安排多少個活動?分析 我們就是想提高教室地利用率,盡可能多地安排活動。考慮容易想到的幾種貪心策略 1 開始最早的活動優先,目標是想盡早結束活動,讓出教室。然而,這個顯然不行,因為最早的活動可能很長,影響我們進...
51Nod 活動安排問題(貪心)
有若干個活動,第i個開始時間和結束時間是 si,fi 只有乙個教室,活動之間不能交疊,求最多安排多少個活動?輸入 第1行 1個數n,線段的數量 2 n 10000 第2 n 1行 每行2個數,線段的起點和終點 10 9 s,e 10 9 輸出 輸出最多可以選擇的線段數量。輸入示例 3 1 52 3 ...