把经典的楼梯问题看作“戴维斯家里有很多楼梯,他喜欢一次爬1、2或3级楼梯。作为一个非常早熟的孩子,他想知道有多少种方法可以到达楼梯顶。”
我的方法是使用带有递归的记忆

# TimeO(N), SpaceO(N), DP Bottom Up + Memoization
def stepPerms(n, memo = {}):

    if n < 3:
        return n
    elif n == 3:
        return 4

    if n in memo:
        return memo[n]
    else:
        memo[n] = stepPerms(n - 1, memo) + stepPerms(n - 2 ,memo) + stepPerms(n - 3 ,memo)
        return memo[n]

我想到的问题是,这个解决方案是自下而上还是自上而下。我的方法是,因为我们一直向下计算上n个值(想象递归树)。我认为这是自下而上的这是对的吗?

最佳答案

不管他们是否有记忆,复述策略通常都是自上而下的方法。底层算法设计是动态规划,传统上是自下而上的。
我注意到你在Python中编写了代码,Python通常对深层资源不满意(少量的是好的,但是性能很快就会受到影响,并且最大的恢复深度为1000——除非我读过之后改变了)。
如果我们制作一个自下而上的动态程序,我们可以摆脱这种重复,我们也可以认识到我们只需要恒定的空间,因为我们只对最后3个值感兴趣:

def stepPerms(n):
    if n < 1: return n
    memo = [1,2,4]
    if n <= 3: return memo[n-1]

    for i in range(3,n):
        memo[i % 3] = sum(memo)
    return memo[n-1]

注意逻辑有多简单,i的appart比值小一,因为位置是从0开始的,而不是从1开始的。

10-07 19:41
查看更多