我有无限的 4 种硬币类型:[1, 5, 25, 50]。如何挑选准确的 48 枚硬币来准确地找 1 美元?(以任何一种有效方式)
我知道如何递归地解决这个问题,但是可以使用 DP 解决它吗?如何?谢谢!
我有无限的 4 种硬币类型:[1, 5, 25, 50]。如何挑选准确的 48 枚硬币来准确地找 1 美元?(以任何一种有效方式)
我知道如何递归地解决这个问题,但是可以使用 DP 解决它吗?如何?谢谢!
让我们想要制造,并且每个硬币n cents
都有无限的供应。S = { S1, S2, S3, .. Sm }
动态规划方法:
要计算解决方案的总数,我们可以将所有集合解决方案分为两组
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
,一种解决方案——我们没有钱,正是一种解决问题的方法——选择不找硬币,或者更准确地说,选择硬币找零
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 美分
解释