Лучший отрезок оценок с одним «пропуском»

тема: DP 1D · уровень: продвинутый

Условие

Перед контрольной учитель вывесил в дневнике подряд результаты мини-тестов класса: за каждый урок — одно число (может быть отрицательным, если за урок получился «минус к настроению»).

Ты выбираешь подряд идущий отрезок уроков, чтобы показать, что прогресс был максимальным. Но разрешают один раз «не учитывать» ровно один урок внутри выбранного отрезка (как будто его не было). Можно и не пропускать ничего.

После пропуска (или без него) должно остаться хотя бы одно число.

Найди максимальную возможную сумму.

Важно: сумма может не помещаться в 32-битный тип (как на олимпиадах). В Python это не проблема.

Формат ввода

Первая строка: целое число n — количество уроков. Вторая строка: n целых чисел a1, a2, ..., an.

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

Одно целое число — максимальная сумма по некоторому непустому подряд идущему отрезку после удаления не более одного элемента внутри этого отрезка.

Ограничения

Пример

Ввод:

5
1 -2 0 3 -1

Вывод:

4

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

Приём: Динамика по префиксу (Кадане) с 2 состояниями

Ключевое наблюдение: «лучший отрезок» удобно строить слева направо. Если фиксировать, что отрезок обязан заканчиваться в текущей позиции i, то для следующего шага достаточно знать всего два числа — максимальную сумму в этом режиме.

Здесь работает 1D DP (динамика по массиву), потому что решение для позиции i зависит только от i-1: либо продолжаем отрезок, либо начинаем новый, а «пропуск» можно сделать один раз.

Заведём состояния:

Переходы для элемента x = a[i]:

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

Сложность: O(n) по времени и O(1) по памяти.

Частая грабля: разрешить пустой отрезок после удаления. Поэтому dp1 нельзя начинать с 0; нужно -inf, и ответ всегда берётся из непустых состояний.

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

Куда дальше