uva 10934 Dropping water balloons
阿新 • • 發佈:2018-04-17
ace 一個 more rdquo output OS i++ 二分法 mem
你有k個一模一樣的水球,在一個n層樓的建築物上進行測試,你想知道水球最低從幾層樓往下丟可以讓水球破掉。由於你很懶,所以你想要丟最少次水球來測出水球剛好破掉的最低樓層。(在最糟情況下,水球在頂樓也不會破)你可以在某一層樓丟下水球來測試,如果水球沒破,你可以再撿起來繼續用。
Input
輸入的每一行包含多組測試,每組測試為一行。每組測試包含兩個整數 k 和 n, 1 <= k <= 100 而 n 是一個 64 位的整數(沒錯,這棟建築物的確很高),最後一組k = 0,n=0 代表結束,這組測試不用處理。
Output
對於每次測試,輸出在最糟情況下,測出水球破掉樓層的最少次數。如果他多於63次,就輸出“More than 63 trials needed.”
扔水球,扔手機,扔水晶球等。。。這題並不是第一次見了,這次就來分析一下解題的思路。
我們最先想到的是二分法,可二分並不是最佳的,因為本題中嘗試的次數有限制,這樣就不能大膽的在二分點上嘗試。
所以我們可以換一種思路:
有k個氣球,丟j次,最多可以確定多少層??
由此可設dp[i][j]為還剩i個氣球,丟了j次後已確定的最高層數。
當dp[i][j]時氣球破了,則可確定dp[i-1][j-1]+1層;若沒有破,則剩下的i個氣球可確定dp[i][j-1]層。
則可得:
dp[i][j]=dp[i-1][j-1]+dp[i][j-1]+1;
附AC代碼:
1#include<bits/stdc++.h> 2 using namespace std; 3 4 long long dp[110][70]; 5 6 int main(){ 7 ios::sync_with_stdio(false); 8 long long n,k; 9 memset(dp,0,sizeof(dp)); 10 for(int i=1;i<64;i++){ 11 for(int j=1;j<64;j++){ 12 dp[i][j]=dp[i-1][j-1]+dp[i][j-1]+1; 13 } 14 } 15 while(cin>>k>>n&&k&&n){ 16 int flag=0; 17 for(int i=0;i<=63;i++){ 18 if(dp[k][i]>=n){ 19 cout<<i<<endl; 20 flag=1; 21 break; 22 } 23 } 24 if(!flag){ 25 cout<<"More than 63 trials needed."<<endl; 26 } 27 } 28 return 0; 29 }
uva 10934 Dropping water balloons