Фонари для парадного проспекта

тема: Интервалы: покрытие и расписание · уровень: средний

Условие

В городе готовят ночной парад по прямому проспекту. Маршрут идёт от точки 0 до точки L.

Подрядчики привезли фонари. Каждый фонарь освещает отрезок проспекта [l_i, r_i] (включая концы). Если поставить несколько фонарей, то освещённой считается любая точка, попавшая хотя бы в один из отрезков.

Нужно осветить весь маршрут [0, L] минимальным числом фонарей. Если это невозможно — сообщите об этом.

Формат ввода

В первой строке записаны два целых числа L и n — длина маршрута и число фонарей. В следующих n строках записаны по два целых числа l_i и r_i — границы освещения i-го фонаря.

Формат вывода

Выведите одно целое число — минимальное количество фонарей, которыми можно полностью осветить [0, L]. Если это невозможно, выведите -1.

Ограничения

Пример

Ввод:

10 4
0 3
2 10
0 10
8 9

Вывод:

1

(Достаточно одного фонаря, который освещает весь отрезок [0, 10].)

Как решать — идея подхода

Приём: Жадный выбор по максимальному правому концу

Ключевое наблюдение: если мы уже осветили всё до точки cur, то следующий фонарь имеет смысл выбирать только среди тех, у кого l_i <= cur (они «подхватывают» освещённый край). Среди них оптимально взять тот, у которого r_i максимален — он даёт самый большой прогресс, и это не может ухудшить ответ: любой другой выбор оставит нас не дальше и потребует не меньше фонарей.

Почему жадность работает: мы строим покрытие слева направо. На каждом шаге важно максимально увеличить правую границу освещения, не создавая разрывов. Если в некоторый момент можно выбрать несколько фонарей, то выбор с меньшим r никогда не поможет покрыть больше, чем выбор с максимальным r, а значит может только увеличить число шагов.

План решения:

Мини-сниппет идеи обновления: while i<n and seg[i].l<=cur: best=max(best, seg[i].r).

Сложность: сортировка O(n log n), проход O(n).

Частая ошибка: проверять достижение как cur == L вместо cur >= L (отрезки могут выходить за L), и забывать случай разрыва, когда best_reach не сдвинулся (тогда сразу -1).

Разберись руками

Маршрут парада идёт по проспекту от 0 до 10. Есть 4 фонаря, каждый освещает свой отрезок. Нужно понять, сколько фонарей минимум нужно, чтобы всё [0,10] стало светлым.

Идея: Держи текущую «первую тёмную точку» слева направо. Каждый раз смотри на все фонари, которые начинаются не позже этой точки, и выбирай среди них тот, который уводит освещение дальше всего вправо. Перепрыгивай к его правому концу и повторяй; если в какой-то момент подходящих фонарей нет — осветить маршрут нельзя.

Решить задачу с автопроверкой на Python →

Куда дальше