寻找多种方法来在硬币变化中赚取总和

Finding number of ways to make a sum in coin changing?

本文关键字:变化 硬币 方法 寻找      更新时间:2023-10-16

给定一个值 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]+...