Я бы подумал о построении решения пошагово, индуктивно:
Доступны монеты 1c, 5c, 10c, 25c (их можно настроить в соответствии с вашими потребностями)
- Минимальные монеты для 1c = 1 X 1c. До 4 центов нам нужны монеты 1с, так как это наименее номинал.
- Для 5 центов у нас есть одна 5c монета. Объединяя это с 4c выше, мы можем генерировать любое число от 1 до 9.
- Для 10 центов нам нужен 1 X 10c. Комбинируя вышеперечисленные три, мы можем сгенерировать любое число от 1 до 19.
- Для 20c нам нужно 2 x 10c, так как 20 делится на 10.
Если вы можете сформулировать проблему индуктивно, возможно, вам будет легче ее решить.
EDIT:
Хорошо, вот еще одна попытка объяснить решение динамического программирования:
Представьте себе таблицу с x
строками (x
- количество различных номиналов) и n
столбцами (n
- это сумма, которую вы должны построить, используя наименьшее количество номиналов). Каждая ячейка в этой таблице представляет отдельную подзадачу и в конечном итоге будет содержать решение для нее. Предположим:
строка 1 представляет собой набор {1c}
, т. Е. В строке 1 вам разрешено использовать бесконечный 1c
строка 2 представляет набор {1c, 10c}
, т.е. в строке 2 вам разрешено бесконечное число 1c
и 10c
строка 3 представляет набор {1c, 10c, 15c}
и так далее ...
Каждый столбец представляет сумму, которую вы хотите построить.
Таким образом, каждая ячейка соответствует одной маленькой подзадаче. Например (для простоты индексы начинаются с 1),
cell(1, 5)
==> построить 5c
используя только {1c}
cell(2, 9)
==> построить 9c
используя {1c, 10c}
cell(3, 27)
==> построить 27c
используя {1c, 10c, 15c}
Теперь ваша цель - получить ответ на cell(x, n)
Solution:
Начните решать таблицу с самой простой задачи. Решение первого ряда тривиально, так как в первом ряду единственное доступное наименование - {1c}
. Каждая клетка в строке 1 имеет тривиальное решение, приводящее к cell(1, n)
= {nx1c}
(n
монет 1c
).
Теперь перейдите к следующему ряду. Обобщая для 2-й строки, давайте посмотрим, как решить для (скажем) cell(2, 28)
, то есть построить 28c
с использованием {1c, 10c}
. Здесь вам необходимо принять решение, включать ли в решение 10c
или нет, и сколько монет. У вас есть 3 варианта (3 = 28/10 + 1)
Choice 1
Возьмите {1x10c}
и остаток от предыдущего ряда (который хранится в cell(1, 18)
). Это дает вам {1x10c, 18x1c}
= 19 coins
Choice 2
Возьмите {2x10c}
и остаток от предыдущего ряда (который хранится в cell(1, 8)
). Это дает вам {2x10c, 8x1c}
= 10 coins
Choice 3
Возьмите не 10c
и остаток от предыдущего ряда (который хранится в cell(1, 28)
). Это дает вам {28x1c}
= 28 coins
Очевидно, что выбор 2 - лучший, так как требует меньше монет. Запишите это в таблицу и продолжайте. Таблица должна быть заполнена по одной строке за раз и внутри строки в порядке возрастания суммы.
Следуя приведенным выше правилам, вы достигнете cell(x, n)
, решением которого будет выбор между n/p + 1
альтернативами, где p
= новейшее наименование в строке x
. Лучший выбор - ваш ответ.
Таблица на самом деле запоминает решения небольших проблем, поэтому вам не нужно решать их снова и снова.