穿越楼梯的不同方式

时间:2017-09-03 12:02:51

标签: python recursion

我正在尝试在python中编写以下代码:有n个楼梯。我想显示从楼梯1到达楼梯n的不同方式(不是总路数)。这里的抓点是我一次可以跳过不超过m个楼梯。请帮忙。注意:m和n将由用户输入。 以下代码显示总数没有方法。但不是所有不同的方式:

# A program to count the number of ways to reach n'th stair


# Recursive function used by countWays
def countWaysUtil(n,m):
  if n <= 1:
      return n
  res = 0
  i = 1
  while i<=m and i<=n:
      res = res + countWaysUtil(n-i, m)
      i = i + 1
  return res

# Returns number of ways to reach s'th stair    
def countWays(s,m):
  return countWaysUtil(s+1, m)



# Driver program

s,m = 4,2
print "Number of ways =",countWays(s, m)

1 个答案:

答案 0 :(得分:2)

这似乎是一种通用的Fibonacci序列,除了f(n) = f(n-1) + f(n-2)而不是f(n) = f(n-1) + ... + f(n-m)。你的代码应该可行,但是如果我没有弄错的话,大量的递归会给你n的更大值(O(m^n)的顺序)带来非常高的复杂性。解决此类问题的关键是记住列表中较低输入值的结果:

def ways_up_stairs(n, m):
    ways = [1] + [None] * n
    for i in range(1, n+1):
        ways[i] = sum(ways[max(0, i-m):i])
    return ways[n]

一些输入和输出示例:

print(ways_up_stairs(4,2)) # 5
print(ways_up_stairs(4,3)) # 7
print(ways_up_stairs(4,4)) # 8

如果您想要实际的步骤序列而不是总和,您可以使用嵌套列表推导相应地轻松调整代码:

def ways_up_stairs(n, m):
    ways = [[(0,)]] + [None] * n
    for i in range(1, n+1):
        ways[i] = [w + (i,) for ws in ways[max(0, i-m):i] for w in ws]
    return ways[n]

print(ways_up_stairs(4,2))
# [(0, 2, 4), (0, 1, 2, 4), (0, 1, 3, 4), (0, 2, 3, 4), (0, 1, 2, 3, 4)]

请注意,您可能需要对代码进行一些调整,例如,不清楚“跳过m步”是否意味着你可以采取1..m1..m+1步骤,但如果你有一些输入的预期结果,那么进行那些“一次性”改编应该是容易。