给出一个带有n
楼梯的楼梯,每个楼梯都包含一个整数值,例如
staircase = [11, 22, 44, 5, 12, 34, 55, 45, 23, 64]
并为楼梯提供一组可能的步长,例如
possible_steps = {3,4,5}
我想找到步骤序列,以便最大化收集值的总和。踏上楼梯后会收集一个值。
示例:
step_sequence
为[3,4]
,值为44+55 = 99
step_sequence
为[4,4,4]
,值为5+45+(out of index is 0) = 50
最佳step_sequence
为[3,4,4]
,可最大化收集的值(44+55+64 = 163
)
问题:
如何使用动态编程来解决问题?或者是动态编程解决问题的最佳方法?
答案 0 :(得分:0)
是的,您可以使用动态编程解决它。如果n
是楼梯中的总数量,m
是可能的步数,则解决方案将具有时间复杂度O(nm)
和空间复杂度O(n)
。我们的想法是问自己,当楼梯在索引i
处结束时,我能得到的最佳总和是多少。有点像硬币变化问题。
function maxSum(stairs, steps) {
let dp = [], maxSteps = steps[0], globalBest = undefined
for (let i = 1; i < steps.length; i++)
if (steps[i] > maxSteps)
maxSteps = steps[i]
for (let i = 0; i < stairs.length; i++) {
let best = undefined
for (let j = 0; j < steps.length; j++) {
if (i - steps[j] == -1 && (best === undefined || best < stairs[i]))
best = stairs[i]
else if (i - steps[j] >= 0 && dp[i - steps[j]] !== undefined &&
(best === undefined || dp[i - steps[j]] + stairs[i] > best))
best = dp[i - steps[j]] + stairs[i]
}
dp[i] = best
if (best !== undefined && i + maxSteps >= stairs.length &&
(globalBest === undefined || globalBest < best))
globalBest = best
}
return globalBest
}
console.log(maxSum([11, 22, 44, 5, 12, 34, 55, 45, 23, 64], [3, 4, 5]))
有一些特殊情况,例如进入楼梯i - steps[j] == -1
或检查我们是否可以到达全局最大值i + maxSteps >= stairs.length
的楼梯尽头。其余的几乎是标准的dp。
此实施也适用于楼梯上的负数(步骤必须为正)。假设您必须在楼梯上收集至少一个数字,如果不可能,则函数返回undefined。