[转载]傻子坐飞机的问题
2008-10-12 19:43
316 查看
最近迷上一些有趣的数学问题了~~~请往下看~~~~
傻子坐飞机的问题:100个人排队乘坐有100个座位的飞机,正常情况时每个都都会对号入坐,但是,第一个上飞机的是个傻子,他随机坐了一个位子,接下来的人上飞机时,如果自己座位被人坐了就会随机找个座位坐下,否则就坐自己坐位。问题:最后一个上飞机的人坐到自己座位的概率是多少?
解题思路:
其实这道题目可以归类到递归中,说到这里,可能好多人不太理解,怎么和递归扯上关系了。递归思路的关键就是一句话"傻子是可以传递的",只要能想明白这句话,题目就迎刃而解。设n个傻子坐飞机的概率是F(n),那么题目的解就是求F(100)的值。
首先假设有题目中的不是100个人,而是n个人,第一个上飞机的是个傻子,他坐到自己座位上的概率是1/n,这是剩下的n-1个都是正常人,他们的座位都没有被占,所以他们100%会全部坐到自己的座位,即在这种情况下最后一个坐到自己座位的概率是1/n.
另外一种情况是这个傻子坐到了最后一个人的位置,那么剩下的人无论怎么坐最后一个人都不会坐到自己的位置,这种情况的概率是0;
第三种情况是傻子坐到了其余n-2个人的座位上,例如他坐到了第m个人的位置(1 < m < 100,概率都是1/n),那么2---m-1号的人都会坐到自己的位置上,因为自己的位置没有人坐。而第m个人由于自己的座位被第一个傻子坐了,所以他要随即坐,这是我们可以他第m个人看做是一个傻子,因为这种情况下他的表现和傻子是一样的,因此这种情况下的概率是1/n*F(n-m+1),即把剩下的n-m+1个人看做是一个n-m+1个人规模的傻子坐飞机的问题。
综上三种情况:这个问题的解就是 F(n)=1/n+0+(F(n-1)+F(n-2)+...+F(2))/n;
看到上述的递推公式出来了,那么题目也就可以解决了。可是等等,我们要求的结果是F(100),而F(100)=1/100+
(F(99)+F(98)+...+F(2))/100,如果按照这个递归公式展开,而F(99)=1/99+(F(98)+F(97)+...+F(2)/99,而且F(98),F(97)每个展开都会产生很多个函数调用,这样的话你的内存马上就有可能耗空。那么如何解决这个问题呢,难道眼睁睁的看着到手的鸭子就让它飞了。当然不行了。
如果你对算法理解稍微深点,主要是循环,也许你马上就能提出一个解决的方法。对了,就是从F(2)开始计算,依次计算F(2),F(3)。。。F(100),每次把求得的结果存到一个数组里,那么比如知道了F(2)到F(9)的值,他们依次存在一个数组f[2],f[3]...,f[9],那么在求F(10)= 1/10+(F(9)+F(8)+...+F(2))/10的时候就不用依次递归来调用求F(9),F(8)的值了,只要依次查找数组f[2],f[3]....f[9]的值代替就好了。
相信看到上面一步好多人已经感觉很不错了,至少内存的问题解决了,那么能不能进一步化简呢?当然能了,只要仔细观察下表达式就能发现问题所在了,每次求F(n)其实最麻烦的就是求后面括号里几项和,刚才我们用数组存储结果来表达上述的值简化了循环调用的麻烦,可是我们发现后几项的和总是从F(2)加起,一直加到F(n-1),所以我们不用每次都计算f[2]+f[3]+...+f[n-1],主要用一个变量例如temp来保存当前的f[2]+f[3]+...f[n-1]即可,那么在计算F(n+1)的时候,我们只要在temp的基础上加上f(n)的值就可以得到f[2]+f[3]+...+f
即可。
题目到此为止了吗?也许你说只要写个小的程序就可以很快知道结果了,可是我可以直接和你说出答案来,不用运行程序,你随便给我一个大一些的,比如1000个人坐飞机,我也可以马上告诉你答案,呵呵。你知道为什么吗?也许有的人已经猜出来了,不是我比较牛,而是答案比较特殊。答案就是1/2!
为什么呢?学过数学归纳法吗?对了,就是用数学归纳法,对于很多的问题,如果我们已经能推出问题的表达式,但是无法证明的时候,我们很多时候用的都是数学归纳法。
证明过程:
1.n=2时,傻子坐到自己位置的概率是1/2,剩下一个人坐到自己的位置,概率1/2.傻子坐到第二个人的位置的时候,最后一个人总不能坐到自己的座位,概率0.因此F(2)=1/2;
2.假设F(2)=F(3)=。。。=F(n-1)=1/2,那么F(n)=1/n+(F(n-1)+F(n-2)+...+F(2))/n.由于F(2)=F(3)=。。。=F(n-1)=1/2,所以F(n)=1/n+(1/2+1/2+...+1/2)/n;(注:括号中共有n-2个1/2),因此可以得到F(n)=1/n+(1/2*(n-2))/n=1/2;
3.所以F(n)=1/2 (当n >= 2时)成立
证明结束!
题目总结:
1.回顾下该题目,首先把这道题能够分解成很多小的问题,找到递归的思路。
2.然后涉及到了一个将递归的程序转换成非递归的问题,这种思路我们平时解题的时候也经常根据具体条件来使用。
3.剩下对于题目的简化就完全是观察的结果,根据题目的特殊表达式进行优化,这个是很有必要的。有的时候,好的
优化可以大大减少计算的复杂度,提高算法的效率。
4.最后数学归纳法也是以前证明问题常用的解法。
所以,好多很复杂的问题都有非常简单美观的输出,这正是算法的魅力!
感谢原作者这么清晰地把解题思路写出来,附原文地址:http://celebration.javaeye.com/blog/212517
其实这个题目是一个典型的概率题,可以从反方向来考虑,即求第N个人无法坐下来的几率~~~
另外附问题的源码:http://blog.csdn.net/alex197963/archive/2007/05/11/1604459.aspx
相关文章推荐
- 傻子坐飞机(概率问题)
- 关于傻子坐飞机问题的答案 (算法的改进)
- 关于傻子坐飞机问题的答案 (算法的改进)
- MYSQL的binary解决mysql数据大小写敏感问题 《转载》
- IE6下兼容问题(转载)
- 【转载】解决浏览器和discuz7.0论坛不兼容的方法,解决快捷回复弹出下载窗口的问题
- 转载:Java中文问题详解,底层编码解剖
- [转载]数学之美 系列十八 - 矩阵运算和文本处理中的分类问题
- c++内存中字节对齐问题详解 [ 转载 ]
- 浏览器兼容问题,一直是自己最头疼,一直回避的问题,今天看得到了一些启发,发奋今天开始研究这个,哈哈,以下为转载文章,好好学习。
- 转载——关于STM32的ADC/DAC问题汇总
- Qt程序的UAC权限问题(转载)
- 人一生中最致命的八个问题[转载]
- 高效的使用Response.Redirect解决一些不必要的问题(转载)
- veritas备份的一些问题(转载)
- 转载--解决VMWare下ubuntu无法全屏的问题
- 5个海盗分配100颗宝石的问题【转载】【数学】
- 解决VB6鼠标滚轮失效问题(转载)
- c#创建exchange邮箱问题(转载)
- (转载)ASP.NET技术初学者学习步骤建议——系统学习ASP.NET技术的学习顺序问题