mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-07 11:36:46 +08:00
build
This commit is contained in:
@@ -4,7 +4,7 @@ comments: true
|
||||
|
||||
# 14.4 Задача о рюкзаке 0-1
|
||||
|
||||
Задача о рюкзаке - это очень хороший вводный пример для динамического программирования и одна из самых типичных форм задач этого класса. У нее существует множество вариантов, например задача о рюкзаке 0-1, задача о полном рюкзаке, задача о многократном рюкзаке и т.д.
|
||||
Задача о рюкзаке является отличным примером для начала изучения динамического программирования и представляет собой одну из наиболее распространенных форм этой задачи. У нее существует множество вариантов, например задача о рюкзаке 0-1, задача о полном рюкзаке, задача о многократном рюкзаке и т.д.
|
||||
|
||||
В этом разделе сначала разберем самый распространенный вариант - задачу о рюкзаке 0-1.
|
||||
|
||||
@@ -18,9 +18,9 @@ comments: true
|
||||
|
||||
<p align="center"> Рисунок 14-17 Пример данных для задачи о рюкзаке 0-1 </p>
|
||||
|
||||
На задачу о рюкзаке 0-1 можно смотреть как на процесс из $n$ раундов решений: для каждого предмета есть два решения - не класть его в рюкзак или положить в рюкзак. Поэтому задача удовлетворяет модели дерева решений.
|
||||
Задачу о рюкзаке 0-1 можно рассматривать как процесс из $n$ раундов принятия решений: для каждого предмета есть два решения - не класть его в рюкзак или положить в рюкзак. Поэтому задача удовлетворяет модели дерева решений.
|
||||
|
||||
Цель задачи - найти "максимальную суммарную стоимость при ограниченной вместимости рюкзака", значит, с большой вероятностью это задача динамического программирования.
|
||||
Цель задачи - найти "максимальную суммарную стоимость при ограниченной вместимости рюкзака", а это с большой вероятностью указывает на задачу динамического программирования.
|
||||
|
||||
**Шаг 1: продумать решения на каждом раунде, определить состояние и тем самым получить таблицу $dp$**
|
||||
|
||||
@@ -351,7 +351,7 @@ $$
|
||||
|
||||
<p align="center"> Рисунок 14-18 Дерево полного перебора для задачи о рюкзаке 0-1 </p>
|
||||
|
||||
### 2. Метод 2: поиск с мемоизацией
|
||||
### 2. Метод 2: мемоизация
|
||||
|
||||
Чтобы каждая перекрывающаяся подзадача вычислялась только один раз, используем таблицу памяти `mem` для хранения решений подзадач, где `mem[i][c]` соответствует $dp[i, c]$ .
|
||||
|
||||
@@ -1110,14 +1110,14 @@ $$
|
||||
|
||||
### 4. Оптимизация пространства
|
||||
|
||||
Поскольку каждое состояние зависит только от состояния в предыдущей строке, можно использовать два массива, которые будут "перекатываться" вперед, и тем самым уменьшить пространственную сложность с $O(n^2)$ до $O(n)$ .
|
||||
Поскольку каждое состояние зависит только от состояния в предыдущей строке, можно использовать два массива, которые будут продвигаться вперед по очереди, и тем самым уменьшить пространственную сложность с $O(n^2)$ до $O(n)$ .
|
||||
|
||||
Если пойти дальше, можно спросить: можно ли оптимизировать память так, чтобы использовать только один массив? Наблюдение показывает, что каждое состояние зависит от клетки прямо сверху и клетки слева сверху. Предположим, что у нас есть только один массив, и в момент начала обхода строки $i$ он еще хранит состояния строки $i-1$ .
|
||||
|
||||
- Если обходить массив слева направо, то к моменту вычисления $dp[i, j]$ значения слева сверху $dp[i-1, 1]$ ~ $dp[i-1, j-1]$ могут уже быть перезаписаны, и правильный результат перехода состояния получить не удастся.
|
||||
- Если же обходить массив справа налево, проблема перезаписи не возникает, и переход состояния вычисляется корректно.
|
||||
|
||||
На рисунке 14-21 показан процесс перехода от строки $i = 1$ к строке $i = 2$ при использовании одного массива. Попробуйте сопоставить его с разницей между прямым и обратным обходом.
|
||||
На рисунке 14-21 показан процесс перехода от строки $i = 1$ к строке $i = 2$ при использовании одного массива. С его помощью удобно понять различие между прямым и обратным обходом.
|
||||
|
||||
=== "<1>"
|
||||
{ class="animation-figure" }
|
||||
|
||||
Reference in New Issue
Block a user