Я не понимаю, как должна выглядеть матрица для метода динамического программирования проблемы с монетами. Скажем, у меня есть номиналы 1c, 5c, 10c и 25c, и я вызываю внесение изменений (10). т. е. я хочу внести сдачу на 10 центов, как должна выглядеть моя окончательная матрица/массив. Мне нужно это знать, так как я хочу назначить массив в начале программы. Я не ищу код здесь.
Если я использую динамическое программирование для размена монет, какой будет матрица для запоминания?
Ответы (2)
Вы можете использовать матрицу, в которой одно измерение показывает сумму, для которой вы рассчитываете прямо сейчас, а другое показывает, какие монеты вы можете использовать — например, первая строка показывает количество способов достичь заданной суммы, используя только монеты 1c. , второй ряд - 1с и 5с, третий - 1с, 5с и 10с и так далее.
Итак, в вашем примере это может выглядеть так:
Sum: 0 1 2 3 4 5 6 7 8 9 10
Ways: 1 1 1 1 1 1 1 1 1 1 1 (using only 1c coins - N x 1c)
1 1 1 1 1 2 2 2 2 2 3 (using 1c and 5c coins - either Nx1c, 1x5c + (N - 5)*1c or 2x5c)
1 1 1 1 1 2 2 2 2 2 4 (using 1c, 5c and 10c coins - one of the above, or 1x10c)
Однако вам не нужно хранить всю матрицу - последней строки всегда должно быть достаточно.
Объяснение того, как избавиться от большей части матрицы:
Предположим, вы нашли ответ, используя только монеты 1c (что не так уж сложно сделать), и он хранится в одном массиве, скажем, DP
. Теперь у вас есть эта информация, и вы хотите знать ответ для монет 1c и 5c.
Можно исходить из sum = 0 to 10
, сохраняя следующий инвариант:
- когда вы вычисляете ответ для
sum
, запись вDP
для каждого числаx
между 0 иsum - 1
включительно показывает количество способов получитьsum
, используя монеты 1c и 5c. Все остальные записи (отsum
до конца массива) содержат ответ только при использовании монет 1c.
И поддерживать его на самом деле довольно просто: когда вы вычисляете ответ для x
, вы знаете:
- количество способов получить
x
используя только монеты 1c - этоDP[x]
, так как мы его еще не перезаписали; - количество способов получить
x
, используя хотя бы одну монету 5c - этоDP[x - 5]
, т.е. количество способов получить то количество монет, которое останется после того, как мы удалим 5c (или 0, еслиx - 5 < 0
).
Затем вы можете просто суммировать эти два числа и сохранить результат в DP[x]
. Затем аналогично продолжайте для остальных монет.
Я думаю, что это хэш-карта, которая отображает сумму в список монет. Таким образом, это будет выглядеть примерно так:
{0 => (),
1 => (1),
2 => (1,1),
3 => (1,1,1),
...
13 => (10,1,1,1)
...
}