Полоска перекусов
Условие
После школы Ира каждый день покупает себе небольшой перекус. Она записала, сколько потратила в каждый из n дней подряд.
Ира нашла у себя купон: если выбрать подряд несколько дней, то суммарно за перекусы в эти дни можно потратить не больше L. Ей хочется понять, какая самая длинная «полоска» подряд идущих дней ей подходит.
Нужно вывести максимальное количество подряд идущих дней, суммарные траты за которые не превышают L.
Формат ввода
В первой строке два целых числа n и L. Во второй строке n целых чисел a1, a2, ..., an — траты по дням.
Формат вывода
Одно целое число — максимальная длина подходящей полоски.
Ограничения
- 1 ≤ n ≤ 5000
- 1 ≤ L ≤ 1 000 000
- 1 ≤ ai ≤ 1000
Пример
Ввод:
7 10
2 3 1 2 4 3 2
Вывод:
4Как решать — идея подхода
Приём: Два указателя (скользящее окно)
Ключевое наблюдение: все траты ai положительные. Значит, если мы расширяем отрезок вправо, его сумма только растёт, а чтобы снова уложиться в лимит L, достаточно двигать левую границу вправо (сумма будет уменьшаться). Это идеально подходит для приёма «скользящее окно».
Идея: поддерживаем текущий отрезок [l..r] и его сумму s. Для каждого нового r добавляем a[r]. Если сумма стала больше L, сдвигаем l, вычитая элементы, пока снова не станет s <= L. Тогда отрезок [l..r] — самый длинный с данным r, потому что левее уже нельзя (там было бы слишком много).
План:
- Инициализируй
l = 0,s = 0,best = 0. - Для каждого
rот 0 доn-1: - прибавь
a[r]кs; - пока
s > L, вычитайa[l]и увеличивайl; - обнови ответ
best = max(best, r - l + 1). - Выведи
best.
Мини-сниппет пересчёта окна: s += a[r]; while s > L: s -= a[l]; l += 1.
Сложность по времени: O(n), потому что каждый указатель проходит массив не больше одного раза.
Частая ошибка: заменять while на if. Сумма может превышать L сильно, и одного сдвига l может не хватить — нужно сдвигать, пока условие не выполнится.
Разберись руками
Есть 7 дней с тратами: 2 3 1 2 4 3 2. Можно выбрать подряд идущие дни так, чтобы сумма была не больше 10. Нужно понять, какая максимальная длина такой полоски.
- Возьми первые 4 дня подряд: 2, 3, 1, 2. Посчитай сумму трат на этой полоске.
- Теперь попробуем расширить эту полоску вправо: добавляем следующий день с тратой 4, получится 12, это больше 10. Что нужно сделать, чтобы снова уложиться в 10 и оставить дни подряд?
- Прогони «два пальца» по всему примеру. Старт: l=0, сумма=0, best=0. На каждом шаге добавляем число справа (это r), а если сумма стала > 10 — убираем числа слева (двигаем l), пока снова не станет ≤ 10. Запиши состояние после каждого шага в формате: l=… r=… sum=… best=…
Идея: Держим один непрерывный кусок дней: расширяем его вправо по одному дню, обновляя сумму. Если сумма стала больше лимита, уменьшаем кусок слева (двигаем левую границу и вычитаем убранные траты), пока снова не уложимся в лимит. Всё время запоминаем максимальную длину подходящего куска.
Решить задачу с автопроверкой на Python →
Куда дальше
- Школьный этап ВсОШ по информатике — как устроен первый этап и план подготовки за четыре недели
- Python на олимпиадах — где языка хватает с запасом, а где начинают значить лимиты — с замерами
- Родителям: подготовка бесплатно — сколько стоит репетитор, что даёт бесплатный маршрут и как понять, что ребёнок занимается