[面试题] 100层楼扔2个鸡蛋,不确定鸡蛋硬度,求最优解。
100层楼扔2个鸡蛋,不确定鸡蛋硬度,求最优解。 + 2000m火车拉煤 + 夜晚大桥,一个手电筒来回
100层楼有2个鸡蛋,需要确定个条件,
1: 把100层楼分多少次,
2: 每次最多有多少层
比如100层, 我分10片, 每次10楼
最坏情况 就是 9(层) + (10-1)(知道第99层没坏,就知道是第100层)
分m片
每片n层
m*n= 100;
求m+n 最小值
a[m][n]
a[10][10] 这样最多试是 9+10-1= 18次
a[11][]
有限层数和蛋数,求即使最坏情况下需要的最少判断次数
两个软硬程度一样但未知的鸡蛋,它们有可能都在一楼就摔碎,也可能从一百层楼摔下来没事。有座100层的建筑,要你用这两个鸡蛋确定哪一层是鸡蛋可以安全落下的最高位置。可以摔碎两个鸡蛋。(参见[两个鸡蛋--一道Google面试题])
这是典型的动态规划问题。假设f[n]表示从n层楼找到摔鸡蛋不碎安全位置的最少判断次数。假设第一个鸡蛋第一次从第i层扔下,如果碎了,就剩一个鸡蛋,为确定下面楼层中的安全位置,必须从第一层挨着试,还需要i-1次;如果不碎的话,上面还有n-i层,剩下两个鸡蛋,还需要f[n-i]次(子问题,实体n层楼的上n-i层需要的最少判断次数和实体n-i层楼需要的最少判断次数其实是一样的)。因此,最坏情况下还需要判断max(i-1,f[n-i])次。
状态转移方程:f[n] = min{ 1+max(i-1,f[n-i]) | i=1..n }
初始条件: f[0]=0(或f[1]=1)
int min_testnumber(int d, int e)
{
int **f=new int *[d+1];
int i,j,k;
for(i=0;i<=d;i++)
f[i]=new int[e+1];
for(i=0;i<=d;i++)
f[i][1]=i;
for(i=0;i<=e;i++)
f[0][e]=0;
for(i=1;i<=e;i++)
{
for(j=1;j<=d;j++)
{
int tmp;
int min_test=0x7FFFFFFF;
for(k=1;k<=j;k++)
{
tmp=f[j-k][i]+1>f[k-1][i-1]+1?f[j-k][i]+1:f[k-1][i-1]+1;
if(tmp<min_test)
min_test=tmp;
}
f[j][i]=min_test;
}
}
int result=f[d][e];
for(i=0;i<=d;i++)
delete[]f[i];
delete[]f;
return result;
}
100层,2个鸡蛋。
100,2 = 14