題目描述
來源
OpenJudge網站 —— 百練習題集-第4151號習題
要求
總時間限制: 1000ms 內存限制: 65536kB
描述
大學生電影節在北大舉辦! 這天,在北大各地放了多部電影,給定每部電影的放映時間區間,區間重疊的電影不可能同時看(端點可以重合),問李雷最多可以看多少部電影。
輸入
多組數據。每組數據開頭是n(n<=100),表示共n場電影。
接下來n行,每行兩個整數(0到1000之間),表示一場電影的放映區間
n=0則數據結束
輸出
對每組數據輸出最多能看幾部電影
樣例輸入
8
3 4
0 7
3 8
15 19
15 20
10 15
8 18
6 12
0
樣例輸出
3
來源
Guo Wei
解題思路
- 本題的算法屬於貪心算法。
- 爲了多看幾部電影,看最早結束的電影是一個最優選擇(不見得唯一)。直覺上來講,看最早結束的電影使得後面餘留更多時間看其他電影。
- 我們來證明:看最早結束的電影是一個最優選擇。
(1)記最早結束的電影D的時間區間是(S0, T0)。
(2)假設李雷可觀看的數量最多的電影中,不包含電影D。這些電影中,最終結束的是電影H,電影H的時間區間是(S1, T1),顯然有T1 >= T0。對於李磊觀看的其他電影中的任一部電影M,有S2 >= T1,這裏S2是電影M的開始時間。
(3)在選擇電影H的情形下,對於李磊觀看的其他電影中的任一部電影M,由於S2 >= T1 >= T0,所以電影M不會與電影D發生衝突。因此,把電影H替換成電影D,不會與其他電影發生時間衝突。這一替換沒有減少所觀看的電影數量,於是電影D至少是一個不比電影H差的選擇。 - 選擇最早結束的電影D後,與電影D衝突的電影必定要排除掉。對於與電影D不衝突的電影的集合A中,該集合中最早結束的電影是一個最優選擇。依次類推,即可求得最終結果。
- 對於n部電影,按結束時間從早到晚排序,能夠快速確定最早結束的電影,時間衝突的電影。
參考答案
while True:
n = int(input())
if n == 0:
break
time_spans = [[int(s) for s in input().split()] for i in range(n)]
time_spans.sort(key=lambda span: span[1]) #按結束時間從早到晚排序
result = [time_spans[0]]
for i in range(1, n):
if time_spans[i][0] >= result[-1][1]:
result.append(time_spans[i])
print(len(result))
測試用例
-
題目描述給出的測試用例只包含一組測試數據,所觀看的3部電影,前一部的結束時間與後一部的開始時間在端點上也沒有重疊。
-
多組測試數據。選中的電影中,前一部的結束時間與後一部的開始時間在端點上重疊。
樣例輸入
3
2 4
1 3
3 5
3
4 5
2 4
1 2
0
樣例輸出
2
3 -
最多看一部。
樣例輸入
3
2 4
1 3
2 5
0
樣例輸出
1
小結
- 本題採用的算法屬於貪心算法。
- 爲了多看幾部電影,看最早結束的電影是一個最優選擇(不見得唯一)。解題思路一節給出了證明。