Все темы
111

Заполняем таблицу, где каждый ответ опирается на предыдущий

Tier 1Закрыто

Где применяется

1. Задача

Жадный подход ошибается, когда лучший выбор прямо сейчас мешает лучшему итогу. Тогда помогает динамическое программирование. Задачу делят на маленькие подзадачи, у которых общая работа. Каждую решают один раз, а её ответ потом берут готовым.

У тебя ряд чисел по дням: выручка за каждый день. В некоторые дни были возвраты, и число уходит в минус. Финансовый отдел спрашивает: какие несколько дней подряд вместе дали больше всего денег? Ответом может оказаться и один день, и весь месяц, но обычно это отрезок где-то посередине.

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

На этот вопрос можно ответить за один проход. Приём, который это даёт, упрощает много задач, которые выглядят страшно. Этот приём и есть тема урока.

Этот шаг из платной части

Бесплатные шаги в начале курса (их 33) открыты всем: урок, задача и тесты. Этот шаг открывается с полным доступом. Начни с бесплатного аккаунта и бесплатных шагов.

Завести бесплатный аккаунтПосмотреть, что входит
Наибольшая сумма сплошного отрезка
maxSubarraySum([-2, 1, -3, 4, -1, 2, 1, -5])
nums
-2
1
-3
4
-1
2
1
-5
curr на каждом i: лучшая сумма отрезка, который кончается на i
curr = -2best = -2

Ищем наибольшую сумму сплошного отрезка. Состояние на i: лучшая сумма отрезка, который кончается ровно на i.

Гонка скорости
Простая рекурсия и таблица снизу вверх на одной и той же лестнице из 18 ступенек

Столбики: сколько раз посчитан ответ для каждой ступеньки i, от 0 до 18.

Одна операция: один вызов или одна клетка таблицы. За каждый кадр все дорожки делают одинаковое число операций, поэтому медленная отстаёт.

Простая рекурсия O(2ⁿ)
операций: 0
Таблица снизу вверх O(n)
операций: 0

 

А если чисел больше

Операции для n чисел и примерное время при 100 миллионах простых операций в секунду. Это оценка по тому же счёту, а не замер.

n = 20
Простая рекурсия21,9 тыс. · меньше 1 мс
Таблица снизу вверх21 · меньше 1 мс
n = 40
Простая рекурсия331,2 млн · 3,3 с
Таблица снизу вверх41 · меньше 1 мс
n = 60
Простая рекурсия5 трлн · 14 ч
Таблица снизу вверх61 · меньше 1 мс

Как узнать

Динамическое программирование (1-D) (Dynamic programming (1-D))

Эти слова в условии значат этот паттерн

  • лучшее/максимум/минимум, заканчивающееся в позиции i
  • число способов дойти, подняться или замостить
  • нельзя брать два соседних элемента
  • минимальная стоимость пути по сетке
  • повторяющиеся подзадачи, одно и то же состояние считается заново

Похоже, но не то

n состояний по O(1) работы дают O(n). Память падает до O(1), когда важны только последние состояния.

На LeetCode

Задачи, где лучший ответ на позиции i зависит только от ответов на одну или две позиции назад, например ограбление домов, подъём по лестнице или лучший отрезок, который кончается здесь. Два бегущих числа заменяют всю таблицу.

Мы используем необходимые куки для работы сайта (вход и язык). Если ты согласишься, мы также загрузим Google Analytics, чтобы видеть, какие страницы читают, и Google reCAPTCHA для защиты форм обратной связи и сообщений об ошибке от спама. Политика конфиденциальности