题目3:一段楼梯共n级台阶,规定每一步只能跨一级或两级或三级。要等上第n级台阶共有几种走法?

斐波那契数列问题:递归或动态规划均可解此类问题。跳台阶是典型应用之一。

思路:我们先从最后开始考虑,因为规定每一步只能跨一级或两级或三级,那么:
从第9级爬上去的可能性有1种; #跨一级:1
从第8级爬上去的可能性有2种; #连续跨一级或者跨两级:11,2
从第7级爬上去的可能性有4种; #穷举:111,12,21,3
然后用递归的思想,把楼梯共10级台阶替换成楼梯共9级台阶/楼梯共8级台阶/楼梯共7级台阶…
我们设爬n级台阶的解法总数为f(n),因为规定每一步只能跨一级或两级或三级,则f(n)=f(n-1)+f(n-2)+f(n-3)。
用穷举法求初始条件:
n=1时,f(n)=1;
n=2时,f(n)=2;
n=3时,f(n)=4;
n=4时,f(n-1)+f(n-2)+f(n-3)=f(n)=f(4)=f(3)+f(2)+f(1);

解法1

#只用有放回抽样算法无法解决抽样顺序问题  
def climb_stair(n):
    z=[]
    nl=[]
    for x in range(n+1):
        nl.append(x)
    nl_3 = nl+nl+nl
    for i in itertools.permutations(nl_3,3):
        if i[0]+2*i[1]+3*i[2]==n:
            z.append(i)
    z=list(set(z))
    z_len=len(z)
    return z,z_len

if __name__=='__main__':
    n=3
    z,z_len=climb_stair(n)
    print(z)
    print(z_len)

解法2
动态规划

def jumpFloor(a):
    n = int(a) #很重要,输入的台阶数目取整
    if n == 1:
        return 1 #Python的return后可以加“;”或者省略
    elif n == 2:
        return 2
    elif n == 3:
        return 4
    else:
        z = jumpFloor(n-1)+jumpFloor(n-2)+jumpFloor(n-3)
        return (z) #可以把变量替代省略,返回值里直接写成公式

n = input('Please give a number:')
print('The number of solutions is:', jumpFloor(n))

解法3

class Solution:
    def __init__(self,n):
        self.n=n
        
    def climbStairs(self):
        """
        :type n: int
        :rtype: int
        """
        res = []
        res.append(1)
        res.append(1)
        res.append(2)
        res.append(4)
        if self.n<=1:
            return 1
        elif self.n==2:
            return 2
        elif self.n==3:
            return 4
        else:
            for i in range(4,self.n+1):
                res.append(res[-1]+res[-2]+res[-3])
            return res[-1]
if __name__=='__main__':
    n = int(input('Please give a number:'))
    sol=Solution(n)
    print(sol.climbStairs())

解法4

def climbStairs(n):
    """
    :type n: int
    :rtype: int
    """
    if(n == 1 or n == 0):
        return 1
    elif n==2:
        return 2
    elif n==3:
        return 4
    else:
        # 假如不是以类的形式, 直接 return 函数() 不需要加 self.
        return climbStairs(n-1) + climbStairs(n-2)+ climbStairs(n-3)
        
if __name__=='__main__':
    n = int(input('Please give a number:'))
    #sol=Solution(n)
    print(climbStairs(n))

解法5

def climbStairs(n):
    """
    :type n: int
    :rtype: int
    """
    temp = [1, 1,2,4]
    result = 0
    if n <= 2:
        return n
    elif n==3:
        return 4
    else:

        while(n > 3):
            result = temp[-1] + temp[-2] + temp[-3]
            temp.append(result)
            n = n - 1

        return result
    
if __name__=='__main__':
    n = int(input('Please give a number:'))
    #sol=Solution(n)
    print(climbStairs(n))

解法6

#记忆搜索
f = [-1] * 50
def fib(n):
    if f[n] != -1:
        return f[n]
    if (n == 0 or n == 1):
        return 1
    elif n == 2:
        return 2
    elif n==3:
        return 4
    else:
        f[n] = fib(n-1) + fib(n-2) + fib(n-3)
        return f[n]
print(fib(4))
print(fib(5))

解法7

#递推 (动态规划思想)
f = [0] * 50
f[0] = 1
f[1] = 1
f[2] = 2
f[3] = 4
for i in range(4,50,1):
    f[i] = f[i-1] + f[i-2] + f[i-3]

print(f[4])
print(f[5])
"""
一次可跳1、2、3级台阶,n级台阶有多少种跳法?最少跳几次?
"""
import itertools
def jumpfloor(n):
    count=0
    arr=[]
    arr_sum=[]
    for i in itertools.permutations(range(n),3):
        if i[0]*1+i[1]*2+i[2]*3==n and i not in arr:
            arr.append(i)
            arr_sum.append(sum(i))
            count += 1
    minnum=min(arr_sum)
    minnum_index=arr_sum.index(minnum)
    min_cs = arr_sum[minnum_index]
    min_zh = arr[minnum_index]
    return arr,count,min_cs,min_zh

n=9
arr,count,min_cs,min_zh=jumpfloor(n)
print('跳法组合:{},共{}种跳法.最佳跳法:{},最佳跳法要跳{}次'.format(arr,count,min_zh,min_cs))

8.跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

# -*- coding:utf-8 -*-
"""
理解为斐波那契数列
"""
class Solution:
    def jumpFloor(self, number):
        # write code here
        if number <2:
            return number
        dp = [1,2]
        for i in range(number-2):
            dp.append(dp[-1]+dp[-2])
        return dp[-1]
s=Solution()
s.jumpFloor(4)
import itertools
def jumpfloor(n):
    count=0
    arr=[]
    arr_sum=[]
    for i in itertools.permutations(range(n),2):
        if i[0]*1+i[1]*2==n and i not in arr:
            arr.append(i)
            arr_sum.append(sum(i))
            count += 1
    minnum=min(arr_sum)
    minnum_index=arr_sum.index(minnum)
    min_cs = arr_sum[minnum_index]
    min_zh = arr[minnum_index]
    return arr,count,min_cs,min_zh

n=9
arr,count,min_cs,min_zh=jumpfloor(n)
print('跳法组合:{},共{}种跳法.最佳跳法:{},最佳跳法要跳{}次'.format(arr,count,min_zh,min_cs))

9.变态跳台阶
题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

# -*- coding:utf-8 -*-
class Solution:
    def jumpFloorII(self, number):
        # write code here
        if number < 3:
            return number
        a = [0,1,2]
        for i in range(3,number+1):
            a.append(sum(a)+1)
        return a[-1]
s=Solution()
s.jumpFloorII(4)