Курс 3.8 — Алгоритмы · Раздел 07 · Урок 7.1

Введение: Знакомство с динамическим программированием

Познакомимся с решением больших задач через маленькие подзадачи и сохранением результатов.

Познакомимся с решением больших задач через маленькие подзадачи и сохранением результатов.
7.1 — Введение: Знакомство с динамическим программированием

Материал урока

Сегодня мы поговорим про один очень умный метод, который помогает решать сложные задачи быстрее. Он называется динамическое программирование.

Почему не всё так просто?

В реальной жизни задачи редко решаются одним действием. Например:

  • Надо построить дом — это не просто "взять и построить", а целая серия шагов: сделать фундамент, возвести стены, поставить крышу.
  • Или решить задачу по математике — иногда приходится разделить её на несколько маленьких шагов.

То же самое и в программировании: большие задачи мы делим на маленькие подзадачи, решаем каждую, а потом собираем всё решение.

Что было раньше

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

Учёные тоже это заметили и придумали, как можно ускорить решение. Одним из таких методов и стало динамическое программирование. Его предложил в 1950-х годах математик Ричард Беллман.

Сначала метод использовали для инженерных и экономических задач, а теперь он помогает и программистам.

Суть динамического программирования

Главная идея:

Если рассмотреть все возможные решения задачи, то можно выбрать наилучшее, но делать это умно, не тратя время на повторные вычисления.

Рекурсия и динамическое программирование: направление решения подзадач
Рекурсия и динамическое программирование: направление решения подзадач

Сравнение с рекурсией

Помнишь, как мы считали факториал или числа Фибоначчи рекурсией?

  • При рекурсии мы идём от большой задачи к маленьким, пока не дойдём до простого факта.
  • Потом поднимаемся обратно и собираем решение.

Проблема в том, что рекурсия часто делает много лишних вычислений. Чтобы это исправить, мы используем мемоизацию — сохраняем уже найденные результаты.

А динамика работает наоборот

В динамическом программировании мы начинаем с маленьких подзадач и постепенно строим решение для большой задачи.

Поэтому его иногда называют "рекурсией наоборот".

Чтобы хранить решения маленьких задач, мы используем таблицу. Иногда это обычный массив, а иногда — целая таблица для более сложных задач.