【发布时间】:2019-12-05 12:01:52
【问题描述】:
我正在努力培养对动态编程问题的良好直觉,但我无法理解问题的特定方面。
我将以 leetcode https://leetcode.com/problems/coin-change/ 上提供的 Coin Change 问题为例
在许多教程中,都提到了一种自下而上的方法,例如这个 - https://www.topcoder.com/community/competitive-programming/tutorials/dynamic-programming-from-novice-to-advanced/
在这种方法中,我们从最佳解决方案开始,然后针对我们的解决方案构建阵列。示例 - 我们找到求和 2 然后 3 的最优解,依此类推。最后,我们将有我们的解决方案。这是我理解的方法。
我无法理解另一种带有记忆的递归方法。我已经为该问题编写了回溯方法,但不确定如何对其应用记忆。
public int changeCoins_BT(int[] coins, int target, int min, int num_curr) {
if(target == 0) {
return min < num_curr ? min : num_curr;
} else if(target < 0) return min;
else if(num_curr > min) return min;
for(int i=0;i<coins.length;i++) {
min = changeCoins_BT(coins,target-coins[i],min,num_curr+1);
}
return min;
}
【问题讨论】:
-
它通常非常简单:记住函数调用以及可以更改的参数。在这种情况下,您需要 mem[target][min][num_curr]。所以在 return min 之前,你存储了值,并且在函数的开头,如果你已经存储了值,你只需返回它
-
感谢您的回复。我们用可以改变的参数来记忆是经验法则吗?
-
如果你有足够的内存,它总是最好的,以防止重新计算是的
标签: algorithm recursion logic dynamic-programming backtracking