动态规划(三)| 豆包MarsCode AI刷题

46 阅读3分钟

复习思考

前两天我们都探讨了动态规划的两种模式,今天我们要来分析一下更复杂的情况,或者说是有更多限制的情况,还记得我们之前说的三要素吗,今天三要素依旧在,但转移方程要考虑更多的情况。

题目示例

小U最近决定挑战一座非常高的楼梯,每次他可以选择走一步或两步,但有一个重要的限制:他不能连续走两步。因此,小U想知道他总共有多少种不同的方式可以从楼梯的底部走到顶端。 你需要帮他计算在给定的楼梯层数下,小U有多少种走法。

题目解析

首先我们可以考虑一下没有限制的情况,即我们可以连续走两步,如此来简单地入门一下。

第一步,老规矩,我们需要先建立dp数组,然后从走1层有多少走法,再考虑到走2层有多少走法,再到后来的n步,因为每一层的走法都是在更少层数的走法上建立起来的,更直接的说,其实我们只需要考虑增添的那段层数的走法就可以了。

第二步,状态转移方程,如果是没有限制的话,第n层的走法可以来源于第n-1层走一步和第n-2层再走两步。但现在我们不可以连续走两步,那么我们需要对每一层的走法分为两种情况,一种是以走一步结尾,一种是走两步结尾,分到两个数组g和h来记录,f为每一层走法的总数即g和h加起来。

但g和h该怎么迭代呢?

g表示最后一步是两步,既然不能连续两步,那么第i层的g应该由第i-1层转化而来

h表示最后一步是一步,那么它的前一步则可以是两步,即关注到g的i-2

  • g[i] = f[i - 1]:表示从第 i-1 层走一步到第 i 层。
  • h[i] = g[i - 2]:表示从第 i-2 层走两步到第 i 层。
  • f[i] = g[i] + h[i]:表示从第 i 层走一步的方式数等于从第 i 层走两步的方式数加上从第 i 层走一步的方式数。

第三步,初始化一些特别的步骤

  • f[0] = 1f[1] = 1,因为从第 0 层到第 0 层只有一种走法,从第 0 层到第 1 层也只有一种走法。
  • g[0] = 1g[1] = 1,因为从第 0 层到第 0 层只有一种走法,从第 0 层到第 1 层也只有一种走法。
  • h[0] = 0h[1] = 0,因为从第 0 层到第 0 层没有走两步的方式,从第 0 层到第 1 层也没有走两步的方式。

题目解答

def solution(n):
    if n == 0:
        return 1
    elif n == 1:
        return 1
    
    # 初始化
    f = [0] * (n + 1)
    g = [0] * (n + 1)
    h = [0] * (n + 1)
    
    f[0] = 1
    f[1] = 1
    g[0] = 1
    g[1] = 1
    h[0] = 0
    h[1] = 0
    
    for i in range(2, n + 1):
        g[i] = f[i - 1]
        h[i] = g[i - 2]
        f[i] = g[i] + h[i]
    
    return f[n]