Ответ 1
Это классическая проблема динамического программирования (заметим сначала, что жадный алгоритм здесь не всегда работает!).
Предположим, что монеты упорядочены так, что a_1 > a_2 > ... > a_k = 1
. Мы определяем новую задачу. Мы говорим, что проблема (i, j)
заключается в том, чтобы найти минимальное количество монет, внесших изменения для j
, используя монеты a_i > a_(i + 1) > ... > a_k
. Задача, которую мы хотим решить, (1, j)
для любого j
с 1 <= j <= n
. Скажем, что C(i, j)
является ответом на проблему (i, j)
.
Теперь рассмотрим экземпляр (i, j)
. Мы должны решить, используем ли мы одну из монет a_i
. Если это не так, мы просто решаем проблему (i + 1, j)
, а ответ - C(i + 1, j)
. Если да, то мы завершим решение, сделав замену для j - a_i
. Чтобы сделать это, используя как можно меньше монет, мы хотим решить проблему (i, j - a_i)
. Мы организуем так, чтобы эти две проблемы были решены для нас, а затем:
C(i, j) = C(i + 1, j) if a_i > j
= min(C(i + 1, j), 1 + C(i, j - a_i)) if a_i <= j
Теперь выясните, что такое начальные случаи и как перевести это на выбранный вами язык, и вам должно быть хорошо идти.
Если вы хотите попробовать свои силы в другой интересной проблеме, требующей динамического программирования, посмотрите Project Euler Проблема 67.