Изменения

Перейти к: навигация, поиск

Динамическое программирование

139 байт убрано, 14:29, 2 ноября 2020
Повтор
<wikitex>
''Динамическое программирование — это когда у нас есть задача, которую непонятно как решать, и мы разбиваем ее на меньшие задачи, которые тоже непонятно как решать. (с) А.Кумок''
=== Принцип оптимальности на подотрезках===
Требуется посчитать функцию $f(1, n)$. Принцип состоит в следующем: пусть для всех отрезков $i$, $j$ (где <tex> u \leqslant i \leqslant j \leqslant v </tex>) известен оптимальный ответ для функции $f(i, j)$. Тогда мы будем вычислять $f(u, v)$ через такие $f(i, j)$. В качестве примера рассмотрим следующую классическую задачу: дана строка длины n, нужно найти максимальный подпалиндром (подпоследовательность максимальной длины, которая является палиндромом). Пусть $d(i, j)$ - ответ на задачу для подстроки, начинающаяся с символа $i$ и заканчивающаяся в символе $j$. Ясно, что $d(i, j) = 0$ для всех $i, j,$ таких что $i > j$ и $d(i, i) = 1$ для всех $i$. Пусть нам нужно посчитать значение для $d(i, j)$, причем значение $d$ для всех $l, r$, таких что <tex> i \leqslant l \leqslant r \leqslant j </tex> уже посчитаны и они оптимальны. Рассмотрим два случая: <br />
# <tex> s(i) \neq s(j)</tex>, тогда <tex> d(i, j) = \max(d(i, j - 1), d(i + 1, j)) </tex> <br /># <tex> s(i) = s(j)</tex>, тогда <tex> d(i, j) = d(i + 1, j - 1) + 2 </tex> <br />
Доказательство:<br />
# Так <tex>s(i) \neq s(j)</tex>, символы $s(i)$ и $s(j)$ не могут входить в максимальный подпалиндром одновременно, то есть либо $s(i)$ входят в максимальный подпалиндром(тогда его длина $d[i, j - 1]$), либо $s(j)$ входит в максимальный подпалиндром (тогда его длина $d[i + 1, j]$), либо оба не входят в максимальный подпалиндром (тогда его длина $= d[i, j - 1] = d[i + 1, j]$). <br />
:* [[Задача о редакционном расстоянии, алгоритм Вагнера-Фишера]]
:* [[Задача о расстоянии Дамерау-Левенштейна]]
:* [[Задача о наибольшей общей подпоследовательности]]
=== Принцип оптимальности на подмножествах ===
'''if''' n <= 1
'''return''' 1
'''if''' fib[n] !== -1 <font color=green>// проверка на то, не посчитали ли мы это число раньше; посчитанные числа хранятся в массиве fib</font> '''return''' fib[n] fib[n - 1] = Fibonacci(n - 1) fib[n - 2] = + Fibonacci(n - 2) '''return''' fib[n - 1] + fib[n - 2]
==См.также==
Анонимный участник

Навигация