所以我写了一个递归算法,用于计算出最少数量的硬币问题'一组特定面额可能达到给定金额。该算法似乎有效,但由于它是递归的,并且在选择一个或另一个之前计算每个可能的选项,我很难想出一种打印出所用面额的方法。所以基本上我可以计算出可以使用的最少硬币数量,但不能计算出哪些硬币。这是我用来驱动它的代码和主要方法。任何简化算法本身的建议也会受到欢迎。
public class DynamicCoinChange {
public static void main(String[] args) {
int[] denoms = {1, 6, 10, 25};
int numCoins = dynamicCoinChange(denoms, 18, 3);
System.out.println(numCoins);
}
public static int dynamicCoinChange(int[] denoms, int amt, int start) {
if (amt == 0 || start < 0) {
return 0;
} else if (amt == 1) {
return 1;
} else if (denoms[start] > amt ||
dynamicCoinChange(denoms, amt, start-1) <
(1 + dynamicCoinChange(denoms, amt-denoms[start], start)) &&
!(dynamicCoinChange(denoms, amt, start-1) == 0)) {
return dynamicCoinChange(denoms, amt, start-1);
} else {
return 1 + dynamicCoinChange(denoms,amt-denoms[start], start);
}
}
}
答案 0 :(得分:1)
无需递归编程最小变化问题。它可以以更简单的迭代方式编程。
int[] denoms = { 1, 6, 10, 25 };
int amt = 18;
double[] min = new double[ amt + 1 ];
for( int i = 1; i < min.length; i++ ) { // We're keeping min[ 0 ] as 0/
min[ i ] = Double.POSITIVE_INFINITY;
}
for( int i = 1; i <= amt; i++ ) {
for( int j = 0; j <= N - 1; j++ ) {
if( denoms[ j ] <= i && min[ i - denoms[ j ] ] + 1 < min[ i ] )
min[ i ] = min[ i - denoms[ j ] ] + 1;
}
}
在这里,您的解决方案将在入口min [amt]。
答案 1 :(得分:1)
我们需要知道两条信息:
根据您的算法,我们知道每当您返回1
时我们都会选择一枚硬币。我们也知道所选择的硬币选择的硬币是start
。因此,我们有信息来解决这个问题。
由于性能在这里不是问题,我们只需传递一个硬币参数,该参数在选择硬币时填充。
public static int dynamicCoinChange(int[] denoms, int amt, int start, ArrayList<Integer> coins) {
if (amt == 0 || start < 0) {
return 0;
} else if (amt == 1) {
coins.add(1);
return 1;
} else if (denoms[start] > amt
// Note that these calls are not guaranteed to be in our solution
// Thus, we make a copy to prevent the calls from modifying our solution
|| dynamicCoinChange(denoms, amt, start-1, new ArrayList<Integer>(coins)) <
(1 + dynamicCoinChange(denoms, amt-denoms[start], start, new ArrayList<Integer>(coins)))
&& !(dynamicCoinChange(denoms, amt, start-1, new ArrayList<Integer>(coins)) == 0)) {
return dynamicCoinChange(denoms, amt, start-1, coins);
} else {
coins.add(denoms[start]);
return 1 + dynamicCoinChange(denoms,amt-denoms[start], start, coins);
}
}
由于这需要我们更改方法签名,我们还必须修改我们的驱动程序:
public static void main(String[] args) {
int[] denoms = {1, 6, 10, 25};
ArrayList<Integer> coins = new ArrayList<Integer>();
int numCoins = dynamicCoinChange(denoms, 7, 3, coins);
for (Integer coin : coins)
System.out.println(coin);
System.out.println(numCoins);
}
在递归调用结束时,coins
应包含按时间顺序选择的硬币列表。