将来この質問を見つける人々のために-
Oscar Lopez と Priyank Bhatnagar が指摘したように、これはコインの変更 (変更を与える、変更を行う) 問題です。
一般に、彼らが提案した動的計画法の解決策は、(おそらく!) 常に最小の項目を使用して必要な合計を生成するという点と、実行速度の点で最適な解決策です。基底数が任意の場合は、動的計画法のソリューションを使用してください。
ただし、基底数が「良い」場合は、より単純な貪欲なアルゴリズムで十分です。
たとえば、オーストラリアの通貨システムでは、 の単位が使用されます$100, $50, $20, $10, $5, $2, $1, $0.50, $0.20, $0.10, $0.05
。残りの金額がゼロ (または 5 セント未満) になるまで、可能な最大の変更単位を繰り返し与えることによって、任意の金額に対して最適な変更を与えることができます。
これは、貪欲なアルゴリズムの有益な実装であり、概念を示しています。
def greedy_give_change (denominations, amount):
# Sort from largest to smallest
denominations = sorted(denominations, reverse=True)
# number of each note/coin given
change_given = list()
for d in denominations:
while amount > d:
change_given.append(d)
amount -= d
return change_given
australian_coins = [100, 50, 20, 10, 5, 2, 1, 0.50, 0.20, 0.10, 0.05]
change = greedy_give_change(australian_coins, 313.37)
print (change) # [100, 100, 100, 10, 2, 1, 0.2, 0.1, 0.05]
print (sum(change)) # 313.35
denominations = [1, 4, 5, 10]
元の投稿 (および)の特定の例ではamount = 8
、貪欲なソリューションは最適ではありません[5, 1, 1, 1]
。しかし、貪欲なソリューションは、動的計画法のソリューションよりもはるかに高速で単純なので、使用できる場合は使用する必要があります。