私はセントで無制限の 4 種類のコインを持っています: [1, 5, 25, 50]. 正確な 1 ドルの変更を行うために正確な 48 枚のコインを選ぶ方法は? (いずれかの有効な方法で)
これを再帰的に解決する方法は知っていますが、DP を使用して解決することは可能ですか? どのように?ありがとう!
私はセントで無制限の 4 種類のコインを持っています: [1, 5, 25, 50]. 正確な 1 ドルの変更を行うために正確な 48 枚のコインを選ぶ方法は? (いずれかの有効な方法で)
これを再帰的に解決する方法は知っていますが、DP を使用して解決することは可能ですか? どのように?ありがとう!
作りたいと思うと、各コインn cents
の無限の供給が与えられます。S = { S1, S2, S3, .. Sm }
動的計画法のアプローチ:
ソリューションの総数を数えるには、すべてのセットのソリューションを2 つのセットに分割できます。
mth coin (or Sm)
。at least one Sm
。count(S[], m, n)
を解の数を数える関数とすると、との和として書ける。count(S[], m-1, n)
count(S[], m, n-Sm)
したがって、次のように定式化されます
count(n,m) = count(n, m-1) + count(n- sm, m)
次の基本ケースを使用します。
count(n,m) =1, n=0
、1 つの解決策 -- お金がありません。問題を解決する方法は 1 つだけです - コインの変更を選択しないか、より正確には、0 のコインの変更を選択する
count(n,m) =0, n<0
、解なし -- 負の金額
count(n,m) =1, n>=1, m<=0
、解決策はありません -- お金はありますが、おつりがありません
可能な解決策は次のとおりです(Haskell):
change d coins | null coins = []
| d==0 = []
| d>=coin = coin:change (d-coin) coins
| otherwise = change d (tail coins) where
coin = head coins
ご了承ください:
以下にいくつかの結果を示します。
*Main> change 100 [50, 25, 5, 1]
[50,50]
*Main> change 99 [50, 25, 5, 1]
[50,25,5,5,5,5,1,1,1,1]
*Main> change 75 [50, 25, 5, 1]
[50,25]
ソリューションで使用するコインの数に制限がある場合:
exactChange d coins n
| d==0 && n==0 = [[]]
| d>0 && n==0 = []
| d==0 && n>0 = []
| null coins = []
| d>=coin = useFirstCoinSolutions ++ skipFirstCoinSolutions
| otherwise = skipFirstCoinSolutions where
coin = head coins
rest = tail coins
useFirstCoinSolutions = map (\x->coin:x) $ exactChange (d-coin) coins (n-1)
skipFirstCoinSolutions = exactChange d rest n
これにより、次の結果が得られます。
*Main> exactChange 100 [50, 25, 5, 1] 48
[[25,25,5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[25,5,5,5,5,5,5,5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[5,5,5,5,5,5,5,5,5,5,5,5,5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]]
したがって、正確な 48 コインで 100 セントを変更するためのすべての可能なソリューションが得られます。
説明