n楼梯值的最大值和使用给定的步骤

时间:2018-03-26 10:05:26

标签: algorithm dynamic-programming

给出一个带有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

问题:

如何使用动态编程来解决问题?或者是动态编程解决问题的最佳方法?

1 个答案:

答案 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。