Python入門習題(94)——OpenJudge百練習題:電影節

OpenJudge百練第4151號習題:電影節

題目描述

來源
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. 本題的算法屬於貪心算法。
  2. 爲了多看幾部電影,看最早結束的電影是一個最優選擇(不見得唯一)。直覺上來講,看最早結束的電影使得後面餘留更多時間看其他電影。
  3. 我們來證明:看最早結束的電影是一個最優選擇。
    (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差的選擇。
  4. 選擇最早結束的電影D後,與電影D衝突的電影必定要排除掉。對於與電影D不衝突的電影的集合A中,該集合中最早結束的電影是一個最優選擇。依次類推,即可求得最終結果。
  5. 對於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))

測試用例

  1. 題目描述給出的測試用例只包含一組測試數據,所觀看的3部電影,前一部的結束時間與後一部的開始時間在端點上也沒有重疊。

  2. 多組測試數據。選中的電影中,前一部的結束時間與後一部的開始時間在端點上重疊。
    樣例輸入
    3
    2 4
    1 3
    3 5
    3
    4 5
    2 4
    1 2
    0
    樣例輸出
    2
    3

  3. 最多看一部。
    樣例輸入
    3
    2 4
    1 3
    2 5
    0
    樣例輸出
    1

小結

  1. 本題採用的算法屬於貪心算法。
  2. 爲了多看幾部電影,看最早結束的電影是一個最優選擇(不見得唯一)。解題思路一節給出了證明。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章