Призы в школьном коридоре

тема: DP 1D · уровень: базовый

Условие

В школе поставили вдоль коридора ряд ящиков с призами. В i-м ящике лежит приз ценностью ai.

Но есть правило: если открыть какой-то ящик, то два соседних с ним ящика сразу блокируются (шум, датчики и всё такое). Поэтому за один проход по коридору нельзя открыть два соседних ящика.

Найди максимальную суммарную ценность призов, которую можно забрать.

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

Формат ввода

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

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

Одно число — максимальная суммарная ценность.

Ограничения

Пример

Ввод:

5
2 7 9 3 1

Вывод:

12

Пояснение: можно открыть ящики с ценностями 2, 9 и 1 (они не соседние), получим 12.

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

Приём: Динамическое программирование по префиксу (House Robber)

Ключевое наблюдение: решение для первых i ящиков зависит только от того, взяли ли мы i-й. Если i-й ящик взяли, то (i-1)-й брать нельзя — правило про соседей.

Отсюда естественно получается динамическое программирование (ДП): идём слева направо и храним лучший результат на префиксе в двух состояниях.

Идея переходов:

Тогда при обработке значения x:

В конце ответ — max(dp0, dp1).

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

Сложность: O(n) по времени, O(1) по памяти — удобно при n до 3000.

Частая ошибка: делать dp1 = dp1 + x (как будто можно брать соседние). Обязательно брать из dp0, иначе вы разрешите запрещённые пары.

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

Куда дальше