題目大致意思就是:有n個水球,它們沒有區別。現在從樓上扔它們,自然當樓層很高時,水球就會炸掉。而且水球炸是有乙個臨界點的,比如在3樓仍下去炸了,那在4,5,6…扔下去都會炸,1 2 就不會炸。
現在問,給你k個水球,最壞情況下至少需要扔多少次,就能確定這個臨界點。
如果只有乙個水球,n層樓,那結果就是n次。因為只能從1樓開始試,最壞到n層。如果你第一次在中間試了,結果炸了,那就gg。
如果有兩個水球,好像不是很好想。第一感覺是二分去找點,二分思路是對的,是最少次數的,但是關鍵是沒這麼多球。
考慮dp,dp[i]表示第一次在i層樓扔球能確定臨界點的最少次數。即當前樓層i扔球,如果炸了就只有1個球了,然後結果就是i-1;如果沒炸,ok,還有兩個球,那我肯定要往樓上試,這時候面臨的問題就相當於n-i層2個球,即dp[n-i]。然後列舉第一次的樓層(1<=i<=n),取最小值(即第一次在哪扔)。dp[0]=0,dp[1]=1,dp[i]=min( 1+max(i-1,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次嘗試,我最大能確定多少樓層?遞推思想和前面類似,有:就是說,如果當前水球炸了,水球數減1(i-1),加上下面的樓層;如果沒炸,水球數不變,加上上面的樓層。最後加1(該樓層)。dp[i][j]=dp[i-1][j-1]+dp[i][j-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 題目描述與樣例輸入不符。還記得劉汝佳的一句話 程式要盡量寫的魯棒,因為哪怕...