复习思考
前两天我们都探讨了动态规划的两种模式,今天我们要来分析一下更复杂的情况,或者说是有更多限制的情况,还记得我们之前说的三要素吗,今天三要素依旧在,但转移方程要考虑更多的情况。
题目示例
小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] = 1和f[1] = 1,因为从第 0 层到第 0 层只有一种走法,从第 0 层到第 1 层也只有一种走法。g[0] = 1和g[1] = 1,因为从第 0 层到第 0 层只有一种走法,从第 0 层到第 1 层也只有一种走法。h[0] = 0和h[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]