【发布时间】:2018-11-05 13:23:47
【问题描述】:
我正在尝试打印最少数量的硬币来进行更改,如果不可能,请打印 -1
在此代码中,变量 int[] c(硬币数组)具有我可以用来计算总和的面额。
int total 有我需要使用硬币计算的总和(无限供应)
public static int mincoinDP(int[] c, int total) {
int[][] a = new int[c.length + 1][total + 1];
for (int i = 0; i <= c.length; i++) {
a[i][0] = 0;
}
for (int j = 1; j <= total; j++) {
a[0][j] = Integer.MAX_VALUE - total;
}
for (int i = 1; i <= c.length; i++) {
for (int j = 1; j <= total; j++) {
if (c[i - 1] > j) {
a[i][j] = Integer.MAX_VALUE - total;
} else {
a[i][j] = Math.min(a[i - 1][j], 1 + a[i][j - c[i - 1]]);
}
}
}
return a[c.length][total];
}
对于 Sum : 4759 和 Array: {31 90 8 36} 正确的输出是:59 我的输出是:60
代码有什么问题?
以下是我的递归解决方案,尝试在 DP 解决方案中应用相同的逻辑。这里的逻辑似乎也有问题。对于相同的输入,它会打印 -2147483595
public static void main(String[] args) {
int[] array = new int[] {31, 90, 8, 36};
System.out.println(mincoin(array, 4759, 0));
}
public static int mincoin(int[] c, int total, int i) {
if (total == 0) return 0;
if (i >= c.length) return Integer.MAX_VALUE;
int x = Integer.MAX_VALUE, y = Integer.MAX_VALUE;
if (total - c[i] >= 0) {
x = 1 + mincoin(c, total - c[i], i);
}
y = mincoin(c, total, i + 1);
return Math.min(x, y);
}
编辑:代码中的问题是:
- DP 版本: if (c[i -1] > j) , 解决方案不成立的情况 可能选择这枚硬币:在这里我们应该接受没有的解决方案 这枚硬币是 a[i-1][j]
- 递归版本:if(i >= c.length), 当我们在这个位置没有任何硬币时,它是终止条件, 在这里我们应该返回无穷大(Integer.MAX_VALUE)和 避免整数溢出返回 Integer.MAX_VALUE - 总计。
虽然我不喜欢这个版本的infinity,但除了这里之外,我没有看到任何好的方式。
【问题讨论】:
-
能否请您解释一下您对此的意图是什么,在您的意见中循环中应该发生什么。请同时解释你的变量,或者至少让它们更有意义。
-
不要只打印硬币的总数,而是打印每个硬币的计数以找出问题。
-
另外,您的递归代码是否有效,还是显示相同的问题?
-
根据 cmets 的要求添加了更多相关细节。
标签: java algorithm dynamic-programming