活動安排問題之二 貪心

2021-07-26 07:20:16 字數 1825 閱讀 7861

有若干個活動,第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

輸出

一行包含乙個整數表示最少教室的個數。

輸入示例

3

1 23 4

2 9

輸出示例

2

以上文字來自51nod,解題**如下

#include#includeusing namespace std;

struct ss[10002];int l[10002];

bool cmp(s x,s y)

printf("%d\n",ans);

return 0;

}

51nod 貪心入門之二 活動安排問題

有若干個活動,第i個開始時間和結束時間是 si,fi 只有乙個教室,活動之間不能交疊,求最多安排多少個活動?分析 我們就是想提高教室地利用率,盡可能多地安排活動。考慮容易想到的幾種貪心策略 1 開始最早的活動優先,目標是想盡早結束活動,讓出教室。然而,這個顯然不行,因為最早的活動可能很長,影響我們進...

貪心 活動安排問題

貪心演算法得到的並不一定是問題的整體最優解。但在這個問題中,貪心演算法最終確定的相容活動集合a的規模最大。描述 11件活動,各自有不同的開始和結束時間。求在所給活動的集合眾選出最大的相容活動子集合。include using namespace std bool a 11 int s 11 int ...

活動安排問題 貪心

有若干個活動,第i個開始時間和結束時間是 si,fi 同乙個教室安排的活動之間不能交疊,求要安排所有活動,最少需要幾個教室?input 第一行乙個正整數n n 10000 代表活動的個數。第二行到第 n 1 行包含n個開始時間和結束時間。開始時間嚴格小於結束時間,並且時間都是非負整數,小於10000...