Расписание школьной конференции
Условие
В школе идёт конференция: в разных кабинетах выступают докладчики. Ты хочешь успеть на как можно больше докладов.
Каждый доклад занимает отрезок времени: начинается в момент s и заканчивается в момент e. Если один доклад заканчивается ровно в момент, когда начинается другой, то на оба успеть можно.
Твоя задача — выбрать максимальное число докладов, на которых ты сможешь побывать целиком.
Формат ввода
В первой строке дано целое число n — количество докладов. Далее в n строках заданы пары целых чисел s_i и e_i — начало и конец i-го доклада.
Формат вывода
Выведите одно число — максимальное количество докладов, которые можно посетить.
Ограничения
1 ≤ n ≤ 2000000 ≤ s_i < e_i ≤ 1000000000- Разрешено посещать доклады подряд, если
e_a ≤ s_b.
Пример
Ввод:
5
1 3
2 5
4 7
6 9
8 10
Вывод:
3
Пояснение: можно, например, выбрать доклады [1,3], [4,7], [8,10].
Как решать — идея подхода
Приём: Жадный выбор по времени окончания
Ключевое наблюдение: чтобы успеть на максимум докладов, важно как можно раньше «освобождать» время для следующих. Поэтому среди докладов, которые можно взять сейчас, выгоднее выбирать тот, у которого конец минимален.
Почему жадный приём работает: если в какой-то момент вы выбрали доклад, который заканчивается позже, его всегда можно заменить на доклад с более ранним концом (при том же старте или позже) и не уменьшить число будущих вариантов — только увеличить или оставить тем же.
План решения:
- Прочитай все пары (s, e).
- Отсортируй доклады по e (по возрастанию). Если e одинаковые, порядок по s не важен.
- Заведи
last_end— время окончания последнего выбранного доклада (сначала что-то вроде -1 или 0). - Иди по отсортированному списку:
- если
s >= last_end, значит доклад не пересекается с уже выбранными (учитывая, чтоe == sразрешено), добавь его в ответ и обновиlast_end = e. - Выведи счётчик выбранных докладов.
Мини-сниппет условия совместимости: if s >= last_end: take.
Сложность: сортировка O(n log n), проход O(n). Память O(n) на список.
Частая ошибка: проверять строго s > last_end и терять случаи, когда один доклад заканчивается ровно в момент начала другого (это разрешено, нужно >=).
Разберись руками
У тебя 5 докладов с временами: [1,3], [2,5], [4,7], [6,9], [8,10]. Ты можешь ходить подряд, если один заканчивается ровно в момент начала другого. Нужно успеть на максимум докладов целиком.
- На старте два доклада пересекаются: [1,3] и [2,5]. Представь наивную мысль: «возьму тот, который идёт подольше». Что выберешь первым?
- После доклада [2,5] следующий должен начинаться не раньше 5. Какой «ближайший по началу» из оставшихся ты можешь взять?
- Сколько докладов получилось по этому наивному пути: сначала «подольше» ([2,5]), потом «пораньше старт» ([6,9])?
- Попробуй другой подход: каждый раз выбираем совместимый доклад, который заканчивается РАНЬШЕ всех остальных. Предскажи, что выберется на каждом шаге (пиши состояние как в вариантах).
Идея: Смысл такой: сначала думай не про «самый длинный», а про то, как быстрее освободить время. Поэтому удобнее смотреть на доклады в порядке их окончания: берёшь тот, который заканчивается раньше всех и не конфликтует с уже выбранными, затем продолжаешь так же дальше.
Решить задачу с автопроверкой на Python →
Куда дальше
- Школьный этап ВсОШ по информатике — как устроен первый этап и план подготовки за четыре недели
- Олимпиада по информатике: с чего начать — два мира олимпиад — ВсОШ и перечневые: этапы, задания и на каком языке писать
- На программиста по олимпиаде: путь по классам — что даёт диплом, куда с ним берут на ИТ-направления и почему решает 9 класс