0062 玻璃珠从楼层上丢下找破碎临界楼层(腾讯笔试题)
最近做的一道腾讯笔试题,大意是:
腾讯深圳总部大厦有39层。你手里有两颗一模一样的玻璃珠。当你拿着玻璃珠在某一层往下扔的时候,一定会有两个结果,玻璃珠碎了或者没碎。这幢大楼有个临界楼层。低于它的楼层,往下扔玻璃珠,玻璃珠不会碎,等于或高于它的楼层,扔下玻璃珠,玻璃珠一定会碎。玻璃珠碎了就不能再扔。现在让你设计一种方式,使得在该方式下,最坏的情况扔的次数比其他任何方式最坏的次数都少。也就是设计一种最有效的方式。
思路:
动态规划。设楼层N
把问题转换为在39-N里找临界楼层。
假如结果都保存在F[40]这个数组里面,那么:
F[N]=40-N,
F[40]=min(max(1,1+F[N-1]),max(2,1+F[N-2]),……,max(N-1,1+F[1]));
已知状态转移方程,代码就简单了:
#include <iostream>
using namespace std;
//gendlee 2016-9-17
#define N 40
int F[N]={0};
void Test()
{
int temp;
for (int loop1=2; loop1<N; ++loop1)
{
F[loop1]=loop1;
for (int loop2=1; loop2<N;++loop2)
{
temp= (loop2>=(1+F[loop1-loop2]))?loop2:(1+F[loop1-loop2]);
if (F[loop1]>temp)
F[loop1]=temp;
}
}
}
int main()
{
F[0]=0;
F[1]=1;
Test();
cout<<F[N-1]<<endl;
return 0;
}结果:9 次
那么实际是怎样操作这9次呢:
先从9楼开始抛第一次;如果没碎,再从17(9+8)楼抛第二次;如果还没碎,再从24(9+8+7)楼抛第三次;如果还没碎,再从30(9+8+7+6)楼抛第四次;如此,每次间隔的楼层少一层。这样,任何一次抛棋子碎时,都能确保最多抛9次可以找出临界楼层。
证明如下:
1、第一次抛棋子的楼层:最优的选择必然是间隔最大的楼层。比如,第一次如果在m层抛下棋子,以后再抛棋子时两次楼层的间隔必然不大于m层(大家可以自己用反证法简单证明)
2、从第二次抛棋子的间隔楼层最优的选择必然比第一次间隔少一层,第三次的楼层间隔比第二次间隔少一层,如此,以后每次抛棋子楼层间隔比上一次间隔少一层。(大家不妨自己证明一下)
3、所以,设n是第一次抛棋子的最佳楼层,则n即为满足下列不等式的最小自然数:
不等式如下: 1+2+3+...+(n-1)+n >= 39
由上式可得出 n = 9
即最优的策略是先从第9层抛下,最多抛9次肯定能找出临界楼层。

浙公网安备 33010602011771号