Понимание и разбор случая динамического программирования

задняя часть алгоритм

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

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

Динамическое программирование — это не столько алгоритм, сколько идея решения проблем. :peach:

Dynamic Programming is a methed for solving a complex problem by breaking it down into a collection of simpler subproblems.

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

Итак, как декомпозировать проблему, становится сутью динамического программирования.

Проблема разложения зависит отстатус проблемыипереходы между состояниями.

  1. Как определить состояние

Нам нужно найти проблему в определенном состоянииОптимальным решением. :strawberry:

Например:

самая длинная возрастающая подпоследовательность (LIS) Для заданного массива длины N найдите самую длинную монотонную самовозрастающую подпоследовательность (не обязательно непрерывную, но порядок не может быть нарушен) Пример: Дан массив A{5, 6, 7, 1, 2, 8} длины 6. Тогда его самая длинная монотонно возрастающая подпоследовательность есть {5, 6, 7, 8} длины 4

Отсюда мы определяем состояние, когда самая длинная возрастающая подпоследовательность dp(i) заканчивается i-м элементом массива. ЛИС всего массива — это максимальное значение dp(1)...dp(n).

Исходя из этого, мы определили состояние проблемы, и теперь мы рассмотрим переход между различными состояниями.

  1. Как найти переходы между состояниями

Во-первых, нам нужно найти состояниеГраничное значение. :watermelon:

Согласно приведенной выше задаче LIS, граничное значение равно 1, когда i=1, а самая длинная возрастающая подпоследовательность равна 1.

Затем нам нужно найти разницу между состояниямисвязь. :banana:

dp(i) = max(1,dp(j)+1...) (0<=j<i) 当array[j]<array[i]

Объясните, в случае, если i-й элемент гарантированно больше, чем j-й элемент, берется максимальное значение самой длинной возрастающей подпоследовательности всех предыдущих элементов плюс 1.

Здесь видно, что уравнение перехода состояния здесь определяет связь между проблемой и подзадачами. Видно, что уравнение перехода состояния представляет собой рекуррентную формулу с условием.

Классические упражнения по динамическому программированию

Вот 6 наиболее классических упражнений по динамическому программированию. :corn:

/**
     * No1.塔树选择和最大问题
     *
     * 一个高度为N的由正整数组成的三角形,从上走到下,求经过的数字和的最大值。
     * 每次只能走到下一层相邻的数上,例如从第3层的6向下走,只能走到第4层的2或9上。
     *      5
     *     8 4
     *    3 6 9
     *   7 2 9 5
     * 例子中的最优方案是:5 + 8 + 6 + 9 = 28
     *
     * 输入:符合塔树的二维数组。
     * 输出:经过的最大值。
     */

/**
     * No2.∑乘法表问题
     *
     * ∑ | a	b	c
     * ——————————————
     * a | b	b	a
     * b | c	b	a
     * c | a	c	c
     *
     * 依此乘法表,对任一定义于∑上的字符串,适当加括号表达式后得到一个表达式。
     * 例如,对于字符串x=bbbba,它的其中一个加括号表达式为i(b(bb))(ba)。
     * 依乘法表,该表达式的值为a。试设计一个动态规划算法,对任一定义于∑上的字符串x=x1x2…xn。
     * 计算有多少种不同的加括号方式,使由x导出的加括号表达式的值为a。
     *
     * 输入:输入一个以a,b,c组成的任意一个字符串。
     * 输出:计算出的加括号方式数。
     */

/**
     * No.3跳台阶
     *
     * 一只青蛙一次可以跳上1级台阶,也可以跳上2级。
     * 求该青蛙跳上一个n级的台阶总共有多少种跳法。
     *
     * 输入:台阶数n。
     * 输出:跳法总数。
     */

/**
     * No.4最长递增子序列(LIS)
     *
     * 给定一个长度为N的数组,找出一个最长的单调自增子序列(不一定连续,但是顺序不能乱)。
     * 例如:给定一个长度为6的数组A{5, 6, 7, 1, 2, 8}。
     * 则其最长的单调递增子序列为{5,6,7,8},长度为4。
     *
     * 输入:一个数组。
     * 输出:最长递增子序列的长度。
     */

/**
     * No.5背包问题
     *
     * 有N件物品和一个容量为V的背包。
     * 第i件物品的大小是c[i],价值是w[i]。
     * 求解将哪些物品装入背包可使价值总和最大。
     *
     * 输入:物品大小数组c,物品价值数组w,背包容量。
     * 输出:最大的价值。
     */

/**
     * No.6最长公共子序列(LCS)
     *
     * 给出两个字符串a, b,求它们的最长的公共子序列。
     *
     * 输入:字符串a和字符串b。
     * 输出:最长的公共子序列的长度。
     */

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

Если вы выполнили упражнение, вот ответы на приведенные выше вопросы,кликните сюда.

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