1212 - 活动安排问题


贪心的适用条件

贪心算法在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。因此利用贪心算法来求最优解,一定要满足当前最优即整体最优这个条件。



策略: 按照开始时间排序优先安排活动,如果冲突,则加一个教室。

简单地理解一下,策略是这样,我们把活动按照开始时间有小到大的顺序排序。假设目前已经分配了 k 个教室( k 初始等于 0 ),对于当前这个活动:

(1) 如果它能安排在 k 个教室里的某一个,则把它安排在其中的任何一个教室里, k 不变。

(2) 否则它和每个教室里的活动都冲突,则增加一个教室,安排这个活动。

这个策略是最优么?

我们想像一下 k 增加 1 的过程: 因为我们是按照开始时间排序的,意味着当前考虑的这个活动开始的时候, k 个教室里都有活动没结束(因为如果有一个教室的活动结束了,我们就可以安排这个活动进入那个教室而不冲突,从而不用增加 k )。这就意味着在这个活动开始的时间点,算上目前考虑的这个活动,有 k+1 个活动正在进行,同一时刻有 k+1个活动在进行,无论我们如何安排教室,都至少需要 k+1 个教室。因为每个教室里不能同时进行两个活动。而我们的策略恰好需要 k+1个教室,所以是最优的。

这个策略也告诉我们,如果从时间轴上“宏观”考虑这个问题。考虑每个时间点同时进行的活动个数,作为这个时间点的厚度(把活动开始和结束时间想像成线段,那么每个时间点有多少条线段覆盖它,可以简单理解为“厚度”),我们至少需要最大厚度那么多个教室——因为那时恰好有最大厚度那么多个活动同时进行,而我们这个贪心策略恰好给了我们一个用最大厚度那么多个教室安排全部活动的一个方案。

如果只需要教室的个数,我们可以把所有开始时间和结束时间排序,遇到开始时间就把厚度加 1,遇到结束时间就把厚度减 1 ,显然最初始和最后结束时的厚度是 0 ,在一系列厚度变化的过程中,峰值(最大值)就是最多同时进行的活动数,也是我们至少需要的教室数。