Ремонт проспекта

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

Условие

В городе есть длинный проспект от отметки 0 до L (всё измеряется вдоль одной линии).

Дорожные бригады уже готовы: каждая бригада умеет отремонтировать ровно один участок проспекта — от l до r (где l < r). Участки можно выбирать в любом порядке, они могут пересекаться.

Мэр хочет, чтобы после выбора бригад весь проспект от 0 до L был покрыт ремонтом (то есть каждая точка на отрезке [0; L] должна принадлежать хотя бы одному выбранному участку). Бригад хочется выделить как можно меньше.

Найдите минимальное число участков, которыми можно покрыть весь проспект. Если это невозможно — выведите -1.

Формат ввода

В первой строке даны два целых числа L и n — длина проспекта и число предложенных участков.

В следующих n строках даны пары целых чисел lᵢ rᵢ — границы i-го участка.

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

Выведите одно целое число — минимальное количество участков, достаточное для покрытия [0; L], или -1, если покрытия добиться нельзя.

Ограничения

Пример

Ввод:

10 4
0 4
3 8
7 10
1 6

Вывод:

3

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

Приём: Жадный выбор для покрытия отрезка

Заметка-переформулировка: нам нужно покрыть [0; L] минимальным числом отрезков. Если мы уже покрыли всё до точки cur, то следующий выбранный отрезок обязан начинаться в l <= cur, иначе между ними будет «дыра».

Ключевое наблюдение: среди всех отрезков, которые начинаются не позже cur, всегда выгодно взять тот, у которого правая граница максимальна. Это жадный шаг: он не ухудшает ответ, потому что любой другой выбор продвинет нас не дальше, а значит может только увеличить число отрезков.

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

Подсказка-формула: обновление дальности — best = max(best, r).

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

Частая ошибка: выбирать отрезок с минимальным l или просто первый подходящий. Нужно именно максимизировать r среди всех с l <= cur, иначе можно получить лишние отрезки или застрять.

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

Проспект от 0 до 10. Есть 4 бригады, каждая может закрыть свой отрезок: [0,4], [3,8], [7,10], [1,6]. Нужно закрыть весь проспект и взять минимум отрезков.

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

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

Куда дальше