Algorithm 更改金额N的方法数
我遇到了这个问题: 给定一个值N,如果我们想换N美分,并且我们有无限量的S={S1,S2,…,Sm}值的硬币,我们可以用多少种方式来换?硬币的顺序无关紧要 例如,对于N=4和S={1,2,3},有四种解决方案:{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 我想出了解决办法:Algorithm 更改金额N的方法数,algorithm,dynamic-programming,Algorithm,Dynamic Programming,我遇到了这个问题: 给定一个值N,如果我们想换N美分,并且我们有无限量的S={S1,S2,…,Sm}值的硬币,我们可以用多少种方式来换?硬币的顺序无关紧要 例如,对于N=4和S={1,2,3},有四种解决方案:{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 我想出了解决办法: // recurrence relati
// recurrence relation
count[N] = count[N-d] for all denomination <= N
Source code
-----------
public static int numWays(int N, int[] denoms) {
if (N == 0)
return 0;
int[] ways = new int[N+1];
ways[0] = 1;
for (int i=1; i<=N; i++) {
ways[i] = 0;
for (int d : denoms) {
if (d <= i) {
ways[i] += ways[i-d];
}
}
}
return ways[N];
}
//递归关系
count[N]=所有面额的count[N-d]让C(i,j)
使用面额为S1,…,Sj的硬币来计算总i
的方法的数量。您的代码实现了以下循环(有序方式)
C(i,m)| i<0=0
|i==0=1
|i>0=sum_{j=1}^mc(i-Sj,m)
链接代码实现了不同的重复(无序方式)
C(i,j)| i<0=0
|i==0=1
|i>0&&j0&&j>0=C(i-Sj,j)+C(i,j-1)
这两个代码之间的差异很微妙:或多或少只是循环的嵌套方式。在转到i+1
之前,您添加了i
的所有术语,但是链接的代码为每个i
添加了j
术语,然后为每个i
添加了j+1
术语,以此类推,当链接代码考虑使用小计i
中的面值-Sj
硬币的可能性时,它隐含地只考虑继续使用面值S1,…,Sj
硬币的那些解决方案,因为i-Sj
的当前总数不包括使用其他硬币的可能性
C(i, m) | i < 0 = 0
| i == 0 = 1
| i > 0 = sum_{j = 1}^m C(i - Sj, m)
C(i, j) | i < 0 = 0
| i == 0 = 1
| i > 0 && j <= 0 = 0
| i > 0 && j > 0 = C(i - Sj, j) + C(i, j - 1)