鸡蛋下降。假设您有一个N层建筑(楼层1到N)和大量鸡蛋。如果蛋从地板T或更高处掉落而且没有破裂则会破裂。你的目标是制定一个策略来确定T的价值,因为对鸡蛋和投掷的数量有以下限制:
这是一个求职面试问题,由在线课程算法,第一部分(普林斯顿)提供。我已经知道如何找到2个鸡蛋所需的最小投掷的一般解决方案,我可以理解版本0到版本3。
我的问题是如何为版本4设计算法。即使有提示我也不知道 该课程给出的提示是: 1 + 2 + 3 + ... + t~1 / 2 * t ^ 2。目标是c =2√2。
答案 0 :(得分:1)
版本4中提示的含义是:
将N分为多个blocks
,例如:
block
1中的第1层,即block 1
中的1层。block 2
中的第2和第3层,即block 2
中的2个楼层。block 3
中的第4,第5和第6,即block 3
中的3个楼层。...
m
中有block m
个楼层。假设这个区块中的楼层T
。然后,将鸡蛋从block m
的第一层扔到block m
的最后一层,找到T
。
Java代码(中文评论):
`
/ **
* Ex 1.4.24
* EggsDrop问题
* ~2logF投掷, ~logF鸡蛋
* @param N
* 楼层高度
* @param F
* 鸡蛋恰好摔碎的楼层
* @return 程序猜到的楼层数
*/
private static int eggsDrop3(int N, int F) {
//debug...
int debugCnt = 0;
int debugEggs = 0;
//区块的左端点相对于一楼的offset
int leftOffset = 0;
//区块的长度
int length = 1;
//result
int f = 0;
//初始第一个区块的左右offset都是0, 因为在第一个区块只有一层楼
while (leftOffset + length <= N) {
//leftOffset + legth表示当前区块的右端点
if (leftOffset + length >= F) {
debugEggs++;
debugCnt++;
//从区块左端点开始遍历
int last = leftOffset + 1;
while (last++ < F)
debugCnt++;
debugEggs++;
f = last - 1;
break;
}
debugCnt++;
leftOffset += length;
length++;
}
o("tosses: " + debugCnt + ", eggs: " + debugEggs);
return f;
}
`
这是算法第4版的github项目。(中文):
答案 1 :(得分:0)
请按以下步骤操作:
从第一层扔掉第一个鸡蛋,然后从第二层,从第四层,从第七层扔掉,依此类推。即连续楼层的差异每步增加一个。
您需要传递T
的投掷次数为
n1 = -1/2 + roundup( sqrt(1/4 + 2T) )
然后使用第二个鸡蛋从最后一个检查点到T线性地进行。这将带你n2
投掷:
n2 = T - Sum { i from 1 to n1 - 1 } (i)
您会看到n2
也是O(sqrt(T))
。因此,投标总数n1 + n2
位于O(sqrt(T))
,这是您想要的。