C++ ——趣味程式碼 三
題目:
現代工程師為了測試出:人從幾樓掉下去(樓層為n層),就會摔死。然後現在給出兩個試用品(代替人), |
摔死之後的試用品將失效。 |
問題:
最少需要測試幾次,才能得到摔碎雞蛋的樓層?方案是什麼?? |
思路分析:
對於這個問題,如果從程式設計的角度而言,最簡單的思路就是用動態規劃的思路來解決。但是我們這次將是從數學角度對問題進行分析。
------------------------------------------
對於這個問題,原始問題---【例如樓層數為100(假設n=100),最少需要幾次(假設為K次)測試,才能得到摔雞蛋的樓層】,直接考慮不容易想到,但是如果我們將這個問題進行一種等價的轉換
這個轉換是解決這個問題的核心,這個轉換是:
轉換問題——【1.兩個測試品,進行k次測試,最多可以測試幾層樓?2.如何發揮這兩個雞蛋的最大效用性】
現在我們以“轉換問題”為模板進行考慮,我們假設兩個測試品為雞蛋,(最基本思想1圖)第一個雞蛋如果破碎,第二個雞蛋就必須只能一層一層的測試了,而且,我們要求進行k次測試就將摔碎雞蛋的樓層必須找到。
--------------------------------------------
第一次測試:
①第一個雞蛋不能放置的樓層太高了,否則,如果第一個雞蛋破碎(只剩下一個雞蛋),那麼第二個雞蛋只能從最底層一層層的向上測試,這樣才能保證第二個雞蛋一定會找到這個臨界樓層(但是效用性太低了),同時這樣可能導致第二個雞蛋可能不再k次測試後得到結果。
②但是也不能放置的樓層太矮了,因為太矮了,如果第一個雞蛋碎了那還好說;
如果沒有破,我們浪費了一次測試機會(雖然還可以繼續使用),也不是浪費了就是效用性降低了,沒有達到最大化效用性。所以第一次雞蛋最好放置在不高不低的位置。
那麼不高不低,到底是多高?
高到如果第一個雞蛋破碎之後第二個雞蛋剛好能完成第K次測試得到結果這個目標。
由此可知,第一次測試所在的樓層高度為K:
①如果第一次測試第一枚雞蛋破碎,則剩下K-1層樓,那麼從第一層樓逐一嘗試,一定可以完成目標。
②如果第一次測試第一枚雞蛋沒有破碎,那麼我們現在只有K-1次測試機會了,而且直到了k樓及其以下都是安全的了。我們消耗了一次測試機會。但是一次測試了K層樓。
然後只有k-1次機會了,第二測試,我們可以在K層的基礎上再增加K-1層,注意這個時候由於我們只有K-1次機會,所以這次只能增加K-1,以保證測試的時候第一枚雞蛋破碎的情況下仍然能完成任務。
於是,重複上述過程,知道最後一次機會,我們總共測試的樓層數為:
K + (K - 1) + (K - 2 ) + ..............+1 = K( K + 1 )/2
然後我們再回到原始問題,100層樓,如果需要K次測試才能測試完成,則必須有
K( K + 1)/2 >= 100
於是我們可以得到,K >= 14,也就是需要14次測試才能得到結果,而且這個過程也將測試方案一併給出了,就是第一次在14樓測試,如果第一枚雞蛋碎了,那麼剩餘13次機會,13層樓未知樓層,恰好,第二次在14 + 13 = 27 樓測試。
那麼我們回到我們原來的問題了
如果不是100層而是N層,需要測試的測試為K!
同上面的數學公式可知: