動態規劃解拋雞蛋 玻璃球 問題

2021-08-07 06:23:30 字數 1533 閱讀 7808

昨天早上看了題經典老題,拋玻璃球,也有的版本是拋雞蛋,可惜昨天早上愣是沒做出來,下午忙別的事去了,到了晚上看了chinaunix上的一篇

討論帖才知道如何解,事實上我一開始對題目的理解就錯了,於是根本沒有想到用dp。今天總算有時間整理一下思路,並把**實現出來了。

題目是這樣的:乙個100層的大廈,你手中有兩個相同的玻璃球。從這個大廈的某一層扔下圍棋

子就會碎,用你手中的這兩個玻璃圍棋子,找出乙個最優的策略,來得知那個臨界層面。

這裡的最優策略指的是在這種策略下無論哪個臨界層面在第幾層,測試的次數最少。我一開始就是把題意理解錯了,給了乙個非最優解,後來看了cu那的討論後才明白了是用動態規劃來做,並可以把題目擴充套件為n層大廈用k個玻璃球來測試。

設f(n,k)為用k個玻璃球來測試n層大廈的臨界層的最少次數,狀態轉移方程如下:

f(n,k)=min+1, 1<=r<=n}

邊界條件:f(n,1)=n-1, f(1,k)=f(0,k)=0

狀態轉移方程可以這樣來考慮,假設在n層樓中的第r層拋一次(對應方程中的"+1"),會有兩種情況發生:

(1)玻璃球碎,說明在第1到第r層樓中必有一層為臨界層,問題轉化為乙個子問題:求f(r,k-1)

(2)玻璃球不碎,說明臨界層在第r+1層到第n層這n-r層樓中,問題轉化為子問題:求f(n-r,k)

因為考慮的是最壞情況下拋球策略的所需測試次數的最小值,所以取這兩種情況中的較大值,並遍歷每乙個可能的r,取其最小值即得到f(n,k)。

實現**如下:

1 #include 

2 #include 

3 #include 

4 #include <

string>

5 #include 

6 #include 

7 #include 

8 #include 

9 #include 

10 #include 

11 #include 

12 #include 

13 #include 

14 #include 

15 #include 

16 #include 

17 #include 

18using

namespace std;

1920#define max_floor 512

21#define max_ball  100

2223int dp(

int n, 

int k)

24 , 1<=r<=n}

40*/

41for(i=2;i<=k;i++)

42for(j=2;j<=n;j++)

43         

51             m[i][j] = min;

52         }

5354return m[k][n];

//f(n,k)55}

5657int main()

58 input: 100 2  output: 14

input: 300 3  output: 13

拋雞蛋 玻璃球或圍棋 優化版

題目 乙個100層的大廈,你手中有兩個相同的雞蛋 玻璃球或圍棋 從這個大廈的某一層扔下雞蛋 玻璃球或圍棋 就會碎,用你手中的這兩個雞蛋 玻璃球或圍棋 找出乙個最優的策略,來得知那個臨界層面。分析 這道題比較直觀的想法是通過二分來尋找,但是二分的解法應該不是最優的。這裡討論通過動態規劃的思路來求解。這...

雞蛋掉落 玻璃球與樓層高度 動態規劃

dp k m 的含義是k個雞蛋 移動m次最多能夠確定多少樓層 第乙個雞蛋扔完,碎了剩下能確定的dp k 1 m 1 下邊的樓層,沒碎剩下能確定的dp k m 1 上 邊的樓層,1本層 dp k m dp k 1 m 1 dp k m 1 1 dp k 1 1 dp 1 m m 可直接給出解 if k...

三個雞蛋(玻璃球 圍棋子)確定樓層問題公式推導

文章原先發表在 1 題目是這樣的 乙個 100層的大廈,你手中有兩個相同的玻璃球。從這個大廈的某一層扔下圍棋子就會碎,用你手中的這兩個玻璃圍棋子,找出乙個最優的策略,來得知那個臨界層面。這裡的最優策略指的是在這種策略下無論哪個臨界層面在第幾層,測試的次數最少。我一開始就是把題意理解錯了,給了乙個非最...