UVA 10934 經典DP,「扔水球」

2021-08-07 13:46:04 字數 1618 閱讀 1201

題目大致意思就是:有n個水球,它們沒有區別。現在從樓上扔它們,自然當樓層很高時,水球就會炸掉。而且水球炸是有乙個臨界點的,比如在3樓仍下去炸了,那在4,5,6…扔下去都會炸,1 2 就不會炸。

現在問,給你k個水球,最壞情況下至少需要扔多少次,就能確定這個臨界點。

如果只有乙個水球,n層樓,那結果就是n次。因為只能從1樓開始試,最壞到n層。如果你第一次在中間試了,結果炸了,那就gg。

如果有兩個水球,好像不是很好想。第一感覺是二分去找點,二分思路是對的,是最少次數的,但是關鍵是沒這麼多球

考慮dp,dp[i]表示第一次在i層樓扔球能確定臨界點的最少次數。

dp[0]=0,dp[1]=1,dp[i]=min( 1+max(i-1,dp[n-i]) )(1<=i<=n)

即當前樓層i扔球,如果炸了就只有1個球了,然後結果就是i-1;如果沒炸,ok,還有兩個球,那我肯定要往樓上試,這時候面臨的問題就相當於n-i層2個球,即dp[n-i]。然後列舉第一次的樓層(1<=i<=n),取最小值(即第一次在哪扔)。

如果有k個水球呢?和2個類似,二維dp:

#include

using

namespace

std;

int dp[100][100000];

int count;

int slove(int n,int k)

int main()

但是問題又來了,現在樓層可能很高(long long),dp陣列開不了這麼大,即使開的了,時間也**。所以列舉樓層就解不了該題。

換個思路,考慮列舉i個水球,j次嘗試,我最大能確定多少樓層?遞推思想和前面類似,有:

dp[i][j]=dp[i-1][j-1]+dp[i][j-1]+1

就是說,如果當前水球炸了,水球數減1(i-1),加上下面的樓層;如果沒炸,水球數不變,加上上面的樓層。最後加1(該樓層)。

#include

#include

#include

#include

using

namespace

std;

long

long dp[110][65];

void init()

}}int main()

}if(!flag) printf("more than 63 trials needed.\n");

}return

0;}

UVa 10934 主要是思路

描述 你有一棟n層的大樓和k個球,詢問至少需要多少次確定球的硬度 分析 對於球的硬度,即是在高度為i時,球沒碎掉,而在高度為i 1時,球碎掉了,此時便可以確定球的硬度為i.主要是對於題目的理解 最壞情況是在最後一層但你不知道 約束在於球的個數有限制 完了分類 能否破掉進行轉移 code includ...

UVa10934 裝滿水的氣球

uva10934 解析 設還剩i個氣球,j次機會時能夠測得的最大高度為d i j 換句話說,就是d i j 層內,可以用i個氣球j次機會測出氣球硬度為j 可以知道 例項 include includeusing namespace std const int maxk 100 const int m...

動態規劃(裝滿水的氣球,uva 10934)

一開始 rte 是因為用了 i64d而沒用 lld。在vj上做的忘了是uva上的題 後來 tle 是因為用了 while scanf lld lld k,n k n 而沒用 while scanf lld lld k,n k 題目描述與樣例輸入不符。還記得劉汝佳的一句話 程式要盡量寫的魯棒,因為哪怕...