mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-05 04:04:22 +00:00
build
This commit is contained in:
@@ -4,7 +4,7 @@ comments: true
|
||||
|
||||
# 14.5 Задача о полном рюкзаке
|
||||
|
||||
В этом разделе сначала решим еще один распространенный вариант задачи о рюкзаке - полный рюкзак, а затем рассмотрим одну из его типичных специальных форм: задачу о размене монет.
|
||||
В этом разделе сначала решим еще одну распространенную задачу о рюкзаке - задачу о полном рюкзаке, а затем рассмотрим один из ее типичных частных случаев: задачу о размене монет.
|
||||
|
||||
## 14.5.1 Задача о полном рюкзаке
|
||||
|
||||
@@ -18,10 +18,10 @@ comments: true
|
||||
|
||||
### 1. Идея динамического программирования
|
||||
|
||||
Задача о полном рюкзаке очень похожа на задачу о рюкзаке 0-1; **разница состоит только в том, что число выборов каждого предмета не ограничено**.
|
||||
Задача о полном рюкзаке очень похожа на задачу о рюкзаке 0-1; **разница состоит только в том, что количество выборов каждого предмета не ограничено**.
|
||||
|
||||
- В задаче о рюкзаке 0-1 каждого предмета существует только один экземпляр, поэтому после того как предмет $i$ помещен в рюкзак, выбирать можно только из первых $i-1$ предметов.
|
||||
- В задаче о полном рюкзаке число экземпляров каждого предмета бесконечно, поэтому после того как предмет $i$ помещен в рюкзак, **выбирать все еще можно из первых $i$ предметов**.
|
||||
- В задаче о полном рюкзаке количество предметов не ограничено, поэтому после того как предмет $i$ помещен в рюкзак, **можно продолжать выбирать из первых $i$ предметов**.
|
||||
|
||||
При этом состояние $[i, c]$ в задаче о полном рюкзаке может изменяться двумя способами.
|
||||
|
||||
@@ -723,7 +723,7 @@ $$
|
||||
dp[n][cap]
|
||||
end
|
||||
|
||||
### Полный рюкзак: динамическое программирование с оптимизацией памяти ##3
|
||||
# ## Полный рюкзак: динамическое программирование с оптимизацией памяти ##3
|
||||
def unbounded_knapsack_dp_comp(wgt, val, cap)
|
||||
n = wgt.length
|
||||
# Инициализация таблицы dp
|
||||
@@ -764,9 +764,9 @@ $$
|
||||
|
||||
### 1. Идея динамического программирования
|
||||
|
||||
**Задачу о размене монет можно рассматривать как частный случай задачи о полном рюкзаке** ; между ними существует следующая связь и следующие различия.
|
||||
**Задачу о размене монет можно рассматривать как частный случай задачи о полном рюкзаке** ; между ними существуют следующие соответствия и различия.
|
||||
|
||||
- Эти две задачи можно взаимно переводить друг в друга: "предмет" соответствует "монете", "вес предмета" соответствует "номиналу монеты", а "вместимость рюкзака" соответствует "целевой сумме".
|
||||
- Эти две задачи можно взаимно преобразовать: "предмет" соответствует "монете", "вес предмета" соответствует "номиналу монеты", а "вместимость рюкзака" соответствует "целевой сумме".
|
||||
- Цель оптимизации противоположна: в задаче о полном рюкзаке нужно максимизировать стоимость предметов, а в задаче о размене монет - минимизировать число монет.
|
||||
- В задаче о полном рюкзаке ищется решение, не превышающее вместимость, а в задаче о размене монет требуется **ровно** набрать целевую сумму.
|
||||
|
||||
@@ -795,7 +795,7 @@ $$
|
||||
|
||||
### 2. Реализация кода
|
||||
|
||||
Большинство языков программирования не предоставляет готовую переменную $+ \infty$ для целых чисел, поэтому обычно приходится заменять ее на максимальное значение типа `int` . Но тогда возникает риск переполнения: операция $+ 1$ в уравнении перехода может переполнить большое число.
|
||||
Большинство языков программирования не предоставляет представление для $+ \infty$ в целочисленном виде, поэтому обычно приходится заменять его на максимальное значение типа `int` . Но тогда возникает риск переполнения: операция $+ 1$ в уравнении перехода может переполнить большое число.
|
||||
|
||||
Поэтому здесь мы используем число $amt + 1$ как обозначение недопустимого решения, потому что для набора суммы $amt$ максимум нужно не больше чем $amt$ монет. Перед возвратом результата проверяем, равно ли $dp[n, amt]$ значению $amt + 1$ ; если да, то возвращаем $-1$ , что означает невозможность набрать целевую сумму. Код приведен ниже:
|
||||
|
||||
@@ -1624,7 +1624,7 @@ $$
|
||||
|
||||
### 1. Идея динамического программирования
|
||||
|
||||
По сравнению с предыдущей задачей теперь целью является число комбинаций. Поэтому подзадача меняется на следующую: **число комбинаций из первых $i$ видов монет, которыми можно набрать сумму $a$**. При этом таблица $dp$ по-прежнему остается двумерной матрицей размера $(n+1) \times (amt + 1)$ .
|
||||
По сравнению с предыдущей задачей здесь целью является число комбинаций. Поэтому подзадача меняется на следующую: **число комбинаций из первых $i$ видов монет, которыми можно набрать сумму $a$**. При этом таблица $dp$ по-прежнему остается двумерной матрицей размера $(n+1) \times (amt + 1)$ .
|
||||
|
||||
Число комбинаций для текущего состояния равно сумме числа комбинаций для двух решений: не брать текущую монету и брать текущую монету. Поэтому уравнение перехода состояния принимает вид:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user