Balls(扔鸡蛋问题)

文章讨论了一个经典的脑筋急转弯问题,即用最少的试验次数找出在多少层楼高度鸡蛋会破碎。给定一定数量的鸡蛋和楼层,要求找出在最坏情况下的最小试验次数。文章提出了动态规划的解决方案,通过初始化状态并进行状态转移,计算出最小的试验次数。
摘要由CSDN通过智能技术生成
var code = "9d83351f-b3a4-4a40-928a-d6b24bbfae2f"

 题目

The classic Two Glass Balls brain-teaser is often posed as:
 

"Given two identical glass spheres, you would like to determine the lowest floor in a 100-story building from which they will break when dropped. Assume the spheres are undamaged when dropped below this point. What is the strategy that will minimize the worst-case scenario for number of drops?"


Suppose that we had only one ball. We'd have to drop from each floor from 1 to 100 in sequence, requiring 100 drops in the worst case.

Now consider the case where we have two balls. Suppose we drop the first ball from floor n. If it breaks we're in the case where we have one ball remaining and we need to drop from floors 1 to n-1 in sequence, yielding n drops in the worst case (the first ball is dropped once, the second at most n-1 times). However, if it does not break when dropped from floor n, we have reduced the problem to dropping from floors n+1 to 100. In either case we must keep in mind that we've already used one drop. So the minimum number of drops, in the worst case, is the minimum over all n.

You will write a program to determine the minimum number of drops required, in the worst case, given B balls and an M-story building.

Input

The first line of input contains a single integer P, (1 ≤ P ≤ 1000), which is the number of data sets that follow. Each data set consists of a single line containing three(3) decimal integer values: the problem number, followed by a space, followed by the number of balls B, (1 ≤ B ≤ 50), followed by a space and the number of floors in the building M, (1 ≤ M ≤ 1000).

Output

For each data set, generate one line of output with the following values: The data set number as a decimal integer, a space, and the minimum number of drops needed for the corresponding values of B and M.

Sample

InputcopyOutputcopy
4 
1 2 10 
2 2 100 
3 2 300 
4 25 900
1 4
2 14
3 24
4 10

 大意:

有k个鸡蛋与n层高的楼,在某一层楼以上扔鸡蛋,鸡蛋会碎,求最小的实验次数(在最坏情况下),找出是哪一层楼

题解:

dp毋庸置疑,可状态千奇百怪

一个奇妙的做法,设f[i][j]为有i次操作有j个蛋能检测的楼高 

如果可以求出所有f[i][j],再枚举最小的i使f[i][k]>=n,问题就迎刃而解了;

我们先考虑这个dp状态的转移

转移:

假设在第i次实验时,手上j个鸡蛋;

如果在第i次实验时,鸡蛋碎了,我们还有j-1个鸡蛋,同时还剩i-1次实验机会,(且我们知道要找的楼层在下面,(其实这个知不知道都无关紧要))

于是就有 f[i][j]+=f[i-1][j-1];

如果在第i次实验时,鸡蛋没碎,那么我们还有j个鸡蛋,同时还剩i-1次实验机会,

于是又有 f[i][j]+=f[i-1][j];

最后还知道了自己当前所处的楼层的信息,所以

f[i][j]+=1;

将上述式子合并就有了最终的状态转移方程式:

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

边界:

case1:

显然,当只有一次实验机会时,在最坏情况只能检测出一层楼

所以,所有的f[1][1,2,3,4,..........]=1;

case2:

当只有一个鸡蛋时,为了保险(鸡蛋不碎),我们会一层一层的尝试,所以能实验的次数就是能检测出的高度,则f[i][1]=i;

有了以上铺垫就可以,解决这道题了

最后献上代码:

#include<iostream>
#include<cstring>
using namespace std;
int T,k,n,cas;
int f[1005][55];//第i次操作有j个蛋能检测的楼高 
void init(){
	memset(f,0,sizeof f);
	for(int i=1;i<=k;i++) f[1][i]=1;//做一次操作只能检测一层楼
	for(int i=1;i<=n;i++) f[i][1]=i;//只有一个蛋时,有几次操作就能检测几层楼 
}
int main(){
	scanf("%d",&T);
	while(T--){
		scanf("%d%d%d",&cas,&k,&n);
		init();
		int ans;
		for(int i=2;i<=n;i++){
			for(int j=1;j<=k;j++){
				f[i][j]=1+f[i-1][j-1]+f[i-1][j];
			}
			if(f[i][k]>=n){
				ans=i;
				break;
			}
		} 
		printf("%d %d\n",cas,ans);
	}
}

眼中若是倾城,便是一生中最爱

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值