我已经使非记忆代码正常工作,该代码计算了m个给定的m值可以表示“ n”的方式。但是我无法在下面的代码中弄清楚为什么备忘录表memoNM返回0而不是答案(在这种情况下为242)。表memoNM只是将先前计算的值存储在递归树中以加快查找速度。有人可以帮帮我吗?
import java.util.ArrayList;
import java.util.Arrays;
public class coinChange {
//Find all ways of representing n in given m inputs
public static void main(String args[]) {
ArrayList<Integer> coinTypes = new ArrayList<Integer>(Arrays.asList(25,
10, 5, 1));//m
int n = 100;
int[][] memoNM = new int[n + 1][coinTypes.size() + 1];
// Initialize memoNM
for (int i = 0; i < memoNM.length; i++) {
for (int j = 0; j < memoNM[0].length; j++) {
memoNM[i][j] = 0;
}
}
int ans = coinChange.coinChange1(n, coinTypes, 0, memoNM);
System.out.println(ans);
}
public static int coinChange1(int n, ArrayList<Integer> coinTypes,
int indexFrom, int[][] memoNM) {
// System.out.println("Coin Types: " + coinTypes.toString() + ", n is: "
// + n + ", m is : " + coinTypes.size());
if (n < 0) {
return 0;
}
if (indexFrom >= coinTypes.size()) {
return 0;
}
if (memoNM[n][indexFrom] > 0) {
return memoNM[n][indexFrom];
}
if (n == 0) {
return 1;
}
/*System.out.println("n is: " + n + " m is: "
+ (coinTypes.size() - indexFrom) + ", memo[n][m] is: "
+ memoNM[n][indexFrom]);
*/
memoNM[n][indexFrom] += coinChange1(n - coinTypes.get(indexFrom),
coinTypes, indexFrom, memoNM);
++indexFrom;
memoNM[n][indexFrom] += coinChange1(n, coinTypes, indexFrom, memoNM);
return memoNM[n][indexFrom];
}
}
更新:
我使用HashMap代替了表来实现了与上面相同的代码,但是我的答案是错误的。对于n = 6和m = 4的正确答案应该是9
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
public class coinChangeMap {
// For an excellent explanation see section 1.7.5 in
// http://composingprograms.com/pages/17-recursive-functions.html
public static void main(String args[]) {
ArrayList<Integer> coinTypes = new ArrayList<Integer>(Arrays.asList(4,
3, 2, 1));
int n = 6;
HashMap<Tuple, Integer> memoMap = new HashMap<Tuple, Integer>();
int ans = coinChangeMap1(n, coinTypes, 0, memoMap);
memoMap.toString();
System.out.println(ans);
}
public static int coinChangeMap1(int n, ArrayList<Integer> coinTypes,
int indexFrom, HashMap<Tuple, Integer> memoMap) {
// System.out.println("Coin Types: " + coinTypes.toString() + ", n is: "
// + n + ", m is : " + coinTypes.size());
if (n < 0) {
return 0;
}
if (indexFrom >= coinTypes.size()) {
return 0;
}
if (n == 0) {
return 1;
}
Tuple tup = new Tuple(n, indexFrom);
if (memoMap.containsKey(tup)) {
return memoMap.get(tup);
}
/*
* System.out.println("n is: " + n + " m is: " + (coinTypes.size() -
* indexFrom) + ", memo[n][m] is: " + memoNM[n][indexFrom]);
*/
int leftAns = coinChangeMap1(n - coinTypes.get(indexFrom), coinTypes,
indexFrom, memoMap);
// memoMap.put(new Tuple(n,indexFrom), leftAns);
int rightAns = coinChangeMap1(n, coinTypes, ++indexFrom, memoMap);
memoMap.put(new Tuple(n, indexFrom), leftAns + rightAns);
return memoMap.get(new Tuple(n, indexFrom));
}
}
我的课程元组是:
public class Tuple {
int n;
int idxFrom;
public Tuple(int n, int indexFrom) {
this.n = n;
this.idxFrom = indexFrom;
}
@Override
public boolean equals(Object other){
if(!(other instanceof Tuple)){
return false;
}
Tuple o = (Tuple)other;
return ((this.n == o.n) && (this.idxFrom == o.idxFrom));
}
@Override
public int hashCode(){
int hashCode = 1;
hashCode = 37 * hashCode + this.n + this.idxFrom;
return hashCode;
}
}
最佳答案
我不能说这是唯一的问题,但是一个问题是两个递归调用之间的indexFrom正在递增。在基于数组的版本中,这导致两个答案未加在一起。哈希图版本将两个值加在一起,但可能会使用错误的键存储结果。