【问题标题】:memoization in dynamic programming动态规划中的记忆
【发布时间】:2017-01-04 06:44:12
【问题描述】:
能否告诉我这个 dp 示例中的记忆化是如何工作的。
dp example problem, codechef
我卡住的部分就像输入是 4 那么为什么代码正在计算
n-1 即 4-1,最佳步长为 4/2 或输入 =10 为什么我们将计算 n-1 直到 1。任何帮助将不胜感激。
动态编程新手,请多多包涵。
【问题讨论】:
-
请不要简单地提供相关资源的链接。把本质变成你的问题。您的问题有两种解决方案:“(4 - 1) / 3 = 1”和“4 / 2 / 2 = 1”。至于问题本身,这个话题here等等
标签:
algorithm
dynamic-programming
【解决方案1】:
动态编程中的记忆只是存储子问题的解决方案。对于输入 n=4,您计算其解决方案。所以你尝试第 1 步。减去 1 + 子问题 n=3 的解。为此,您需要解决问题 n=3,因为您之前没有解决它。所以你再次尝试第 1 步,直到你得到输出 0 的 n = 1 的基本问题。
在针对当前问题尝试第 1 步后,您尝试第 2 步,这意味着除以 n,然后再尝试第 3 步。您为每个子问题尝试每一步,但是因为您在每个子问题中存储了最佳值,所以您可以在以下情况下使用它它再次发生。
例如,当您尝试第 1 步后返回 n=4 时,您尝试第 2 步,您会发现可以使用 n / 2 并且因为您已经计算了 n=2 的最佳值,所以您可以输出 1 + n=2 的最优值,即 1,所以总共 2。
【解决方案2】:
链接解释得很清楚。如果F(n) 是将n 转换为1 的最少步骤数,那么对于任何n > 1,我们都有以下递归关系:
F(n) = 1 + min(F(n-1), F(n/2), F(n/3)) // if n divisible by 2 and 3
F(n) = 1 + min(F(n-1), F(n/2)) // if n divisible by 2 and not 3
F(n) = 1 + min(F(n-1), F(n/3)) // if n divisible by 3 and not 2
F(n) = 1 + F(n-1) // all other cases
对于您的情况,n=4,我们必须计算 F(n-1) 和 F(n/2) 来决定哪个是最小值。
至于第二个问题,当n=10我们会先评估F(9)。在此评估期间,所有值F(8), F(7), ... F(2)都被计算和记忆。然后,当我们评估 F(10/2) = F(5) 时,只需在 memoized values 数组中查找值即可。这将节省大量计算。
【解决方案3】:
也许你可以在 JS 中做如下操作;
function getSteps(n){
var fs = [i => i%3 ? false : i/3, i => i%2 ? false : i/2, i => i-1],
res = [n],
chk;
while (res[res.length-1] > 1) {
chk = false;
fs.forEach(f => !chk && (chk = f(res[res.length-1])) && res.push(chk));
}
return res;
}
var result = getSteps(1453);
console.log(result);
console.log("The number of steps:",result.length);