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. 为了多看几部电影,看最早结束的电影是一个最优选择(不见得唯一)。解题思路一节给出了证明。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章