Домашки на вечера
Условие
В школе учитель выдал список из n небольших домашних заданий. Каждое задание занимает ровно один вечер, и за один вечер можно сделать не больше одного задания.
Про каждое задание известно число d[i] — последний день, не позже которого его можно сдать (если сделать в день d[i], это нормально). Вечера нумеруются с 1.
Нужно понять, сколько максимум заданий можно успеть сдать, если выбирать порядок выполнения самому.
Формат ввода
В первой строке дано целое число n. Во второй строке дано n целых чисел d[1], d[2], ..., d[n].
Формат вывода
Выведите одно целое число — максимальное количество заданий, которые можно сдать вовремя.
Ограничения
- 2 ≤ n ≤ 8000
- 1 ≤ d[i] ≤ 1000000000
Пример
Ввод:
5
1 2 2 3 3
Вывод:
3
Пояснение: можно сдать задания в дни 1, 2 и 3 (например, с дедлайнами 1, 2 и 3). Остальные уже не успеют в оставшиеся вечера до своих дедлайнов.
Как решать — идея подхода
Приём: Жадный алгоритм: сортировка по дедлайнам
Ключевое наблюдение: все задания одинаковые (каждое занимает ровно 1 вечер), значит важен только порядок. Если у двух заданий дедлайны a <= b, то выгоднее (или хотя бы не хуже) ставить раньше задание с дедлайном a: оно «строже», а более позднее почти всегда можно сдвинуть. Это типичный жадный обмен: если в расписании стоит b перед a, их можно поменять местами и не ухудшить выполнимость.
Отсюда приём: сортируем дедлайны по возрастанию и идём слева направо, пытаясь занять следующий свободный вечер.
План:
- Считать
nи массивd. - Отсортировать
dпо возрастанию. - Завести
day = 0— сколько вечеров уже занято. - Для каждого
deadlineпо порядку: - если можно поставить ещё одно задание до дедлайна, то делаем его: условие
day + 1 <= deadline. - тогда увеличиваем
dayи ответ. - Вывести ответ.
Мини-сниппет проверки:
if day + 1 <= deadline: day += 1
Сложность: сортировка O(n log n), проход O(n), память O(1) сверх массива.
Частая ошибка: пытаться «занимать именно день deadline» или хранить календарь до max(d) (он может быть до 1e9). Здесь нужен только счётчик занятых вечеров.
Разберись руками
Есть 5 домашних заданий, каждое занимает ровно один вечер. У каждого задания есть дедлайн (последний день сдачи): 1, 2, 2, 3, 3. Нужно выбрать порядок, чтобы успеть сдать максимум заданий вовремя.
- Какой порядок заданий логичнее пробовать, если хочешь успеть максимум до дедлайнов?
- Прогоним руками идею: держим «следующий свободный день» day (сначала 0) и счётчик done (сначала 0). Идём по дедлайнам 1,2,2,3,3. На каждом шаге пытаемся занять следующий день (day+1). Если day+1 <= дедлайн — успели, иначе пропускаем это задание. Заполни состояния после каждого дедлайна.
- Сколько заданий получилось сдать вовремя в этом прогоне?
Идея: Сначала ставим задания с более ранними дедлайнами вперед. Потом идём по этому списку и каждый раз пытаемся занять самый ранний ещё свободный вечер; если он не позже дедлайна — делаем задание, иначе пропускаем и идём дальше.
Решить задачу с автопроверкой на Python →
Куда дальше
- Школьный этап ВсОШ по информатике — как устроен первый этап и план подготовки за четыре недели
- На программиста по олимпиаде: путь по классам — что даёт диплом, куда с ним берут на ИТ-направления и почему решает 9 класс
- Вердикты судьи: WA, TLE, RE, PE, CE — что значит каждый код проверяющей системы и где искать причину