在动态编程中,我们大部分时间都会得到巨大的结果散列。然而,最初它只包含从第一个最小的最简单(底部)案例中获得的结果,并且通过使用这些初始结果并在其上进行计算,我们最终将合并到目标。此时,大部分时间散列中的最后一项是目标(步骤3完成)。然后我们将不得不处理它以获得所需的结果。
一个完美的例子可以找到总计达到目标的最小立方体数量。目标是500,我们应该得到[5,5,5,5],或者如果目标是432,我们必须得到[6,6]。
所以我们可以在JS中执行这个任务如下:
function getMinimumCubes(tgt){
var maxi = Math.floor(Math.fround(Math.pow(tgt,1/3))),
hash = {0:[[]]},
cube = 0;
for (var i = 1; i <= maxi; i++){
cube = i*i*i;
for (var j = 0; j <= tgt - cube; j++){
hash[j+cube] = hash[j+cube] ? hash[j+cube].concat(hash[j].map(e => e.concat(i)))
: hash[j].map(e => e.concat(i));
}
}
return hash[tgt].reduce((p,c) => p.length < c.length ? p:c);
}
var target = 432,
result = [];
console.time("perf:");
result = getMinimumCubes(target);
console.timeEnd("perf:");
console.log(result);
在此代码
所以,hash = {0:[[]]},
是步骤1;最终准备hash[tgt]
的嵌套循环实际上是第3步,返回阶段的.reduce()
仿函数是第4步,因为它构成了散列的最后一项(hash[tgt]
),通过筛选出最短结果给我们期望的结果所有结果中总计达到目标值。
对我而言,第2步有点毫无意义。不是因为提及递归,而是因为意义。除此之外,我从未在动态编程中使用过也没有看到过递归方法。最好用while
或for
循环来实现。