切換
舊版
前往
大廳
主題

ZeroJudge - a261: 10934 - Dropping water balloons 解題心得

Not In My Back Yard | 2019-10-12 20:02:03 | 巴幣 2 | 人氣 318

題目連結:


題目大意:
給定兩正整數 k 、 n (1 ≦ k ≦ 100 , n < 2 ^ 63;當 k = n = 0 時,代表輸入結束),代表有 k 顆一模一樣的水球,以及一棟有 n 層樓的建築。

試問:最少需要丟幾次水球,才能保證知道水球從哪層樓丟下會剛好摔破?如果次數超過 63 次,請輸出「More than 63 trials needed.」;否則,直接輸出所需的次數。

注:水球破了就破了,無法復原。因此 k 顆都破了就無法得知結果(除非第 k 顆剛好可以測出)。而沒有破的水球,可以重複利用。



範例輸入:
2 100
10 786599
4 786599
60 1844674407370955161
63 9223372036854775807
0 0


範例輸出:
14
21
More than 63 trials needed.
61
63


解題思維:
原本的題目敘述相當抽象(對本人來說,不管是 ZeroJudge 還是 UVa 原題都是),所以稍作調整變成上面的題目大意。

我們定義一個二維陣列 Di, j ,i 代表擁有的水球數、 j 代表投水球的「次數」,而  Di, j 代表的是在一開始有 i 顆水球的情況下,且丟了 j 次水球(不一定是同一顆)後可以確定到多高的樓層數。

因此,來討論水球破與不破的情形:
水球破了 → 那麼就是從丟的樓層往下找,因為要確定到盡可能高的樓層,所以本次丟的樓層應為第  Di-1, j-1 + 1 層。(因為水球破了一顆且能丟的次數少了一次)。
水球沒破 → 那就是看從丟的樓層往上找,最高可以再找多少層,此時即 Di, j-1 (因為水球沒破,所以數量不變但次數仍少了一次)。

所以,最後我們可以得出:
Di, j = Di-1, j-1 + 1 + Di, j-1
且初始條件(邊界條件)是沒有水球或是沒有可丟的次數之情況:
對於任意非負整數 i , Di, 0 = D0, i = 0

然後從邊界條件往上推得測試資料可能會出現的情況。接著,每輸入一組(k, n)時,就從 Di, 1 、 Di, 2 、…… 開始找,找到第一個 Di, j 所確定的樓層大於等於 n 。此時即為所求。如果 j > 63 ,則輸出「More than 63 trials needed.」。

此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

想請問大大,水球破了和沒破不是兩種狀態嗎?為什麼可以直接相加!
2019-10-12 23:05:19
Not In My Back Yard
先上示意圖:
https://images2.imgbox.com/5a/20/EsCb1ZCT_o.png

可以相加的原因是因為,現在有 i 顆水球且預計要丟 j 次。那麼,如果我選定一個樓層數為 XD ,並在該層樓丟擲水球。

如果破了,就是往下繼續找,因為還不知道最低是不是第 XD 樓;
沒破,要往上找,因為水球沒破,當然不知道會在第幾層樓破。

那我要怎麼選擇第 XD 樓實際應該是哪一層?

因為我預計要丟 j 次,而且是丟剛好 j 次,不多不少。所以就是看我有 i - 1 顆球且要丟 j - 1 次時可以決定的樓層數。加一之後就是第 XD 樓。(因為水球破了,會往 XD 樓下開始找)

而這是我丟 j 次能決定的最低樓層。最高可以決定到的樓層就是取決於有 i 顆丟 j - 1 次的情況。

因為狀態轉移後,都是丟 j - 1 次;而狀態轉移前,丟了一次。總計 j 次,因此可以相加。

以上。希望有釐清你的疑慮。
2019-10-13 01:09:30
謝謝你那麼晚還仔細地回復,大致理解了!!
2019-10-13 11:33:20

更多創作