雙蛋問題拓展及python實現

1、問題描述

TT層樓,NN個雞蛋,雞蛋是相同的,臨界樓層是指從某個樓層之上拋下來,都會碎,但從這個樓層之下拋下來,都不會碎。沒有碎的雞蛋可以重複使用。試假設能找到這個臨界樓層需要拋投的最少次數。

2、背景與原理

看李永樂的視頻:https://www.bilibili.com/video/av96214853

M(T,N)M(T,N)爲在從TT層樓,NN個蛋的情況下需要拋投的最少次數,情況有多少種呢。當然是t種,從每一層都拋出一個雞蛋試一下。

現在就要得到這t個拋投實驗中的最小拋投次數。設Mk(T,N)M_k(T,N)爲從k1kTk(1\le{k}\le{T})層樓拋下1個雞蛋進行測試而得到的拋投數。這t種拋投有通用的遞推模式:
假設在k層樓進行拋投,會產生兩種情況:

碎了:問題規模變爲:M(T,N1)M(T, N-1)

沒碎:問題規模變爲:M(Tk,N)M(T-k, N)
所以有:

Mk(T,N)=max[M(k,N1),M(Tk,N)]+1M_k(T,N) = max[M(k, N-1), M(T-k, N)] + 1,也就是求出這種情況下最大的拋投次數。

M(T,N)=min[M1(T,N),M2(T,N),M3(T,N)......Mk(T,N)]M(T,N)= min[M_1(T,N), M_2(T,N), M_3(T,N) ...... M_k(T,N)]

可以用一個數學公式表示:
M(T,N)=min1kT{max[M(k,N1),M(Tk,N)]} M(T,N)=\min_{1\le{k}\le{T}}\{max[M(k,N-1),M(T-k,N)]\}

3、爲什麼可以遞歸求解呢

這裏是我自己的想法,覺得不對的可以留言指正。
首先來看上面的數學公式,M(T,N)M(T,N)M(k,N1)M(k,N-1)M(Tk,N)M(T-k,N)來決定,而且一旦NN決定了,那麼M(T,N)M(T,N)就可以由N1N-1NN這兩列的數來確定,具體是由這兩列的那些數來決定依賴k的值。然後又有:
1.當N=1N=1時,總是有M=TM=T

2.當T=1T=1時,總是有M=1M=1
所以可以得到M(T,N)M(T,N)的兩條邊界值。如下圖所示。
在這裏插入圖片描述

可以根據紅色圈的數求出藍色圈的值,然後按列一個個求取,就可以把其他位置的值都求出來。就是根據N1N-1列和NNTT層以上的值求出TTNN列的值。

4、python代碼

#!/usr/bin/env python 
# -*- coding:utf-8 -*-
import numpy as np
def my_max(num1, num2):
    if (num1 >= num2) :
        max_num = num1
    else:
        max_num = num2
    return max_num

def init_array(floors, eggs):
    array = [[0 for i in range(eggs)] for i in range(floors)]
    array = np.array(array)
    array[0,:] = 1
    for i in range(floors):
        array[i,0] = i+1
    return  array

def get_array(floors, eggs):
    array = init_array(floors,eggs)
    print(array)
    print("-----------------------------")
    for e in range(1,eggs):
        for f in range (1,floors):
            temp_m = [[0 for i in range(1)] for i in range(f)]
            temp_m = np.array(temp_m)
            for k in range (f):
                m1 = array[k,e-1]
                m2 = array[(f-k-2),e]
                temp_m[k-1,0] = my_max(m1,m2)+1
            array[f,e] = min(temp_m[:,0])
    return array

def get_result(floors, eggs):
    array = get_array(floors,eggs)
    result = array[floors-1,eggs-1]
    print(array)
    print("---------------------------------")
    return result

if __name__ == '__main__':
    test = get_result(16,10)
    print("result =",test)

5、結果

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章