【发布时间】:2021-07-06 18:27:04
【问题描述】:
所以我一直在努力掌握动态编程。我可以说我真的理解自上而下的记忆方法,但自下而上的方法让我很困惑。我能够解决自上而下切割的杆,但我必须寻求自下而上的解决方案。我只是不明白何时使用一维数组或二维数组。然后自下而上的 for 循环只是令人困惑。谁能帮我从概念上理解这两个代码的区别?
// Top Down Memoizaton:
const solveRodCuttingTop = function(lengths, prices, n) {
return solveRodCuttingHelper(0, lengths, prices, n);
};
function solveRodCuttingHelper(idx, span, prices, n, memo = []) {
// BASE CASES
if (idx === span.length || n <= 0 || prices.length !== span.length) {
return 0;
}
let included = 0, excluded = 0;
memo[idx] = memo[idx] || [];
if (memo[idx][n] !== undefined) return memo[idx][n];
if (span[idx] <= n) {
included = prices[idx] + solveRodCuttingHelper(idx, span, prices, n - span[idx], memo);
}
excluded = solveRodCuttingHelper(idx + 1, span, prices, n, memo);
memo[idx][n] = Math.max(included, excluded);
return memo[idx][n];
}
// Bottoms up
const solveRodCuttingBottom = function(lengths, prices, n) {
const rods = Array.from({length: n + 1});
rods[0] = 0;
let maxRevenue = - Infinity;
for (let i = 1; i < rods.length; i++) {
for (let j = 1; j <= i; j++) {
maxRevenue = Math.max(maxRevenue, prices[j - 1] + rods[i - j])
}
rods[i] = maxRevenue
}
return rods[prices.length];
};
const lengths = [1, 2, 3, 4, 5];
const prices = [2, 6, 7, 10, 13];
【问题讨论】:
-
到底有什么令人困惑的地方?对于 TD,您说:“我无法解决这个问题,因为它太大了。我需要先解决小问题,然后再建立大解决方案”。对于 BU,您说:“我从解决较小的问题开始,然后建立大的解决方案”。无论哪种方式,您最终都会先解决小问题并构建大问题,这只是您从哪里开始的问题。到目前为止,备忘录哈希和DP表是存储子问题解决方案的两种方式。
标签: javascript recursion