寻找多种方法来在硬币变化中赚取总和
Finding number of ways to make a sum in coin changing?
给定一个值 N,如果我们想为 N 美分做零钱,并且我们有无限供应 S = { S1, S2, .. , Sm} 值硬币,我们有多少种方法可以进行更改?硬币的顺序并不重要。
例如,对于 N = 4 和 S = {1,2,3},有四种解决方案:{1,1,1,1},{1,1,2},{2,2},{1,3}。所以输出应该是 4。对于 N = 10 且 S = {2, 5, 3, 6},有五种解决方案:{2,2,2,2,2}、{2,2,3,3}、{2,2,6}、{2,3,5} 和 {5,5}。所以输出应该是 5。
现在,我有一个疑问。为什么我们不能做这样的事情,
arr[i] = arr[i-1] + arr[i-2] + arr[i-3]
这基本上是,arr[i]
存储使总和i
的方法的数量。我在这里给出的方法有点类似于n stairs problem
,即我可以爬固定数量的楼梯,也就是说,假设一次爬 1 个楼梯或一次爬 2 个楼梯,我必须计算从底部到达顶部的路径总数。为什么我们不能在这个问题中使用类似的方法?
为什么我们不能在这个问题中使用类似的方法?
它不起作用,因为在n个楼梯问题中,顺序很重要。例如,如果您要爬 5 个楼梯,{1, 2, 1, 1} 被视为与 {1, 1, 2, 1} 不同。
然而,在进行更改问题中,只有每个硬币的总数计数,而不是您添加它们的顺序,因此如果您赚取 5 美元,{$1, $2, $1, $1} 与 {$1, $1, $2, $1} 相同。因此,简单的记忆方法不起作用,您需要存储到达arr[i]的所有可能方法,而不仅仅是总数。
例如,假设您尝试用 6 美元和 1 美元赚 2 美元。你不能只是将赚 4 美元的方法数量添加到赚 5 美元的方法数量上,因为(例如)赚 4 美元的方法之一是 {$1, $1, $2}(你可以加上 $2 来赚 6 美元,即 {$1, $1, $2, $2}),而赚 5 美元的方法之一是 {$1, $2, $2} (您可以添加 $1 以赚取 $6 {$1, $2, $2, $1})。
但是,{$1, $2, $2, $1} 和 {$1, $1, $2, $2} 不应单独计算。
> Samgak的回答解释了做出改变与一次爬1或2步楼梯的不同之处:顺序对于做出改变并不重要,但是当你爬楼梯时,顺序很重要。
您可以使用动态编程来解决问题,但您需要更复杂的状态。让我们a[i][j]
是仅使用硬币的前j面额来改变i单位货币的方法的数量。因此,a[0][0]=1
,对于 i 大于 0,对于 j 大于 0,a[i][0] = 0
a[i][j] = a[i][j-1] + a[i-Sj][j-1] + a[i-2*Sj][j-1]+...
- 最小硬币更换问题(自上而下方法)
- C++取消引用指针.为什么会发生变化
- 为什么在读取文件大小时文件IO速度会发生变化
- 为什么cudaMemGetInfo报告设备内存总量的变化
- 如何避免LED在循环状态变化中闪烁?
- 当 I2C 值在C++中发生变化时收到通知
- Gtkmm 会不断检查 Gtk::日历上的所选日期是否发生变化
- 如何在硬币兑换问题中找到硬币的数量
- 当我调用对象的方法时,对象的成员会发生变化
- 为什么向量内部的指针在从函数返回时会发生变化?
- 硬币兑换:找到多种方法来重现给定的总和
- 如何在 c++ 中循环中使用频率变化的声音?
- 为什么 C++ 中的零会发生变化
- 我如何计算硬币变化中的不同组合
- 动态规划:硬币变化
- 硬币的变化(硬币的价值是m的幂)
- 是硬币变化算法,输出仍可由DP解决的所有组合
- 自底向上的方法,以最小的硬币数量的变化
- 硬币变化自下而上的动态规划
- 寻找多种方法来在硬币变化中赚取总和