昨天早上看了題經典老題,拋玻璃球,也有的版本是拋雞蛋,可惜昨天早上愣是沒做出來,下午忙別的事去了,到了晚上看了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層的大廈,你手中有兩個相同的玻璃球。從這個大廈的某一層扔下圍棋子就會碎,用你手中的這兩個玻璃圍棋子,找出乙個最優的策略,來得知那個臨界層面。這裡的最優策略指的是在這種策略下無論哪個臨界層面在第幾層,測試的次數最少。我一開始就是把題意理解錯了,給了乙個非最...