Если вы решаете проблему смены монет, лучшим способом является использование множества способов внесения изменений с частичным набором доступных номиналов и добавление нового номинала d
путем обновления массива следующим образом. :
for i = d upto N
a[i] += a[i-d]
Ваша реальная проблема заключается в обратном: поиск деноминаций на основе общего количества способов. Обратите внимание, что если вы знаете один d
, вы можете удалить его из массива way, выполнив в обратном порядке описанную выше процедуру:
for i = N downto d
a[i] -= a[i-d]
. Вы можете найти наименьший доступный номинал, найдя первые 1 в массиве ( кроме значения по индексу 0, который всегда равен 1). Затем, как только вы найдете наименьший номинал, вы можете убрать его влияние на массив путей и повторять до тех пор, пока массив не обнулится (кроме первого значения).
Вот полное решение в Python :
def rways(A):
dens = []
for i in range(1, len(A)):
if not A[i]: continue
dens.append(i)
for j in range(len(A)-1, i-1, -1):
A[j] -= A[j-i]
return dens
print(rways([1, 0, 1, 1, 2]))
Возможно, вы захотите добавить проверку ошибок: если вы найдете ненулевое значение, отличное от 1, при поиске следующего наименования, то исходный массив недопустим.
Для справки и сравнения приведем код для вычисления способов внесения изменений из набора наименований:
def ways(dens, N):
A = [1] + [0] * N
for d in dens:
for i in range(d, N+1):
A[i] += A[i-d]
return A
print(ways([2, 3, 4], 4))