兔子問題(四種方法):已知一對兔子每一個月可以生一對小兔子,而一對兔子出生後.第三個月開始生小兔子,假如沒有發生死亡,則每個月有多少兔子?

兔子問題:已知一對兔子每一個月可以生一對小兔子,而一對兔子出生後.第三個月開始生小兔子,假如沒有發生死亡,則每個月有多少兔子?

#按照兔子的對數進行考慮,完全是一個斐波拉契數列
#方法一:遞歸調用,每次遞歸的時候有大量重複計算,效率低,可將其調用的過程轉化成一顆二叉樹進行分析,
# 二叉樹的總結點個數不超過(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   



發佈了301 篇原創文章 · 獲贊 365 · 訪問量 159萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章