uva 10934 Dropping water balloons

你有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 } 

 

 

 

posted @ 2018-04-17 21:00  Kiven#5197  阅读(286)  评论(0编辑  收藏  举报