1. 程式人生 > >C++ ——趣味程式碼 三

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!

同上面的數學公式可知:

100層樓扔兩個雞蛋的問題