兔子问题(四种方法):已知一对兔子每一个月可以生一对小兔子,而一对兔子出生后.第三个月开始生小兔子,假如没有发生死亡,则每个月有多少兔子?

兔子问题:已知一对兔子每一个月可以生一对小兔子,而一对兔子出生后.第三个月开始生小兔子,假如没有发生死亡,则每个月有多少兔子?

#按照兔子的对数进行考虑,完全是一个斐波拉契数列
#方法一:递归调用,每次递归的时候有大量重复计算,效率低,可将其调用的过程转化成一颗二叉树进行分析,
# 二叉树的总结点个数不超过(2^n-1)个,由于其是不完全二叉树,那么函数计算的次数必小于(2^n-1),
# 时间复杂度为O(2^n);递归调用的深度为n,空间复杂度为O(n)
def rabbit(month):
    return 1 if (month<3) else (rabbit(month - 1) + rabbit(month - 2))

if __name__ == '__main__':
    month=int(input('输入月数:'))
    print('兔子每个月的数量变化:')
    for i in range(1,month+1):
        print(2*rabbit(i),end='\t')
#方法二:非递归循环方式,将前两项的计算结果保存起来,无重复计算,时间复杂度为O(n),空间复杂度为O(1)
def rabbit(month):
    i,j=0,1
    while i<month+2:
        if i>0:
            print(2 * i)
        i,j=j,i+j

if __name__ == '__main__':
    month=int(input('输入月数:'))
    print('兔子每个月的数量变化:')
    rabbit(month)
#方法三:直接利用数学公式法:f(n)={[(1+5^0.5)/2]^n - [(1-5^0.5)/2]^n}/(5^0.5),
# 时间复杂度为O(1),空间复杂度为O(1)
import math
def rabbit(n):
    return (pow((1 + math.sqrt(5.0)) / 2, n) - pow((1 - math.sqrt(5.0)) / 2, n)) / math.sqrt(5.0)

if __name__ == '__main__':
    month=int(input('输入月数:'))
    print('兔子每个月的数量变化:')
    for i in range(1,month+1):
        print(2*int(rabbit(i)),end='\t')

#方法四:矩阵的乘法,时间复杂度仅为O(log n),空间复杂度为O(1),时间效率虽然低,但不够实用,源码太过繁琐
import  copy
def rabbit(month):
    M = [[1, 1], [1, 0]]
    N = [[1, 1], [1, 0]]
    P = [[1, 1], [1, 0]]
    while month<=2 and month>0:
        print(2*P[0][0],end='\t')
        month-=1
    if month>2:
        print(2 * P[0][0], end='\t')
        print(2 * P[0][0], end='\t')
    while month > 2:
        # P[0][0] = M[0][0] * N[0][0] + M[0][1] * N[1][0]
        # P[0][1] = M[0][0] * N[0][1] + M[0][1] * N[1][1]
        # P[1][0] = M[1][0] * N[0][0] + M[1][1] * N[1][0]
        # P[1][1] = M[1][0] * N[0][1] + M[1][1] * N[1][1]
        for i in range(2):  # i 可以取0 1; P的 0 1 行
            for j in range(2):  # j ,P的0 1 列
                # 参与的总是:M的i行,N的j列
                if i == 0:
                    P[i][j] = M[0][0] * N[0][j] + M[0][1] * N[1][j]
                if i == 1:
                    P[i][j] = M[1][0] * N[0][j] + M[1][1] * N[1][j]
        print(2*P[0][0],end='\t')
        M=copy.deepcopy(P)
        month -= 1

if __name__ == '__main__':
    month=int(input('输入月数:'))
    print('兔子每个月的数量变化:')
    rabbit(month)

方法四的公式如下:

 f(n)      f(n-1)        1    1

[                 ] = [          ]^(n-1)

 f(n-1)    f(n-2)        1    0

运行结果:

输入月数:6

兔子每个月的数量变化:

2     2     4     6     10   16   



已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页