首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

递归完美解决"傻子造成的有关问题" :)

2012-02-16 
递归完美解决傻子造成的问题 :)昨天晚上快睡觉的时候在这里看到了这样的一个帖子,问题是:100个人排队乘

递归完美解决"傻子造成的问题" :)
昨天晚上快睡觉的时候在这里看到了这样的一个帖子,问题是:

"100个人排队乘坐有100个座位的飞机,正常情况时每个都都会对号入坐,但是,第一个上飞机的是个傻子,他随机坐了一个位子,接下来的人上飞机时,如果自己座位被人坐了就会随机找个座位坐下,否则就坐自己坐位。问题:最后一个上飞机的人坐到自己座位的概率是多少?? "

我对此特别感兴趣就想了一个晚上,算是找到了自己比较满意的答案0.5.虽然我看到回帖的人中有很多都说的是0.5,但是我是有我自己的解决思路,在这里拿出来和大家一起探讨一下;有什么不对的地方希望大家多指教.如果你能指出我解答之中的错误请给我指出来,送8分。

考虑一般的问题,不管一共有多少人,设为n个人,n个位置.
反面考虑,和有的人一样求最后一个人(即第n个人)不能坐到自己位置的概率为P(n);
设倒数第二个人不能坐到自己位置的概率为P(n-1),
则P(n)   =   P(n   -   1)   +   (1/(n   -   (n   -   1)   +   1))   *   P(n   -   1);
第一个人不能坐到自己的位置的概率显然是(n-1)/n;
第二个人不能坐到自己的位置的概率是:1/n   (只有傻子可能坐他的位置);
即这些人中第k个人(k   <=   n   &&   k   >   2)不能坐到自己的位置是;
P(k)   =   P(k-1)+{1/[n-(k-1)+1]}*P(k-1);

用数学规纳法证明(我其实是通过一般的情况才看出来的这个规律):
证:
最基本的情况就是当k=3的时候;
第三个人的位置只可能被第一个人坐和被第二个人坐;
        1.当被第一个人坐时,而第二个人坐自己的位置概率为(1/n)*1;
        2.当被第二个人坐时,肯定第一个人把第二个人的位置坐了第二个人再把
            三个人的位置坐了(第二个人坐的时候有n-1个位置他可以随便选),
            则概率为:(1/n)*[1/(n-1)]   =   {1/[n-(3-1)+1]}*P(2);
    则第三个人不能坐到自己位置的概率为;(1/n)+{1/[n-(3-1)+1]}*(1/n);
            即:P(3)   =   P(2)+{1/[n-(3-1)+1]}*P(2);  
假设第k个人不能坐到自己的位置的概率P(k)=P(k-1)+{1/[n-(k-1)+1]}*P(k-1)成立;
则第k+1个人的位置让别人坐了的概率为P(k+1);
    第k+1个人的位置只可能让他前面的k个人给坐了,有两种情况:
            1.可能把第k个人的位置坐了的前k-1个人中的一个坐了他的位置,则第k个人
                肯定坐自己的位置。显然这部分的概率和第k个人的位置被坐的概率一样即
                为:P(k);
            2.可能就是第k个人把他的位置给坐了,那肯定第k个人的位置就是让前k-1个
                中的一个家伙给坐了概率为P(k),而第k个人又把第k+1个人的位置坐了概率
                1/(n-k+2)(当第k个人坐的时候有n-k+1个位置随便他选).则这部分的概率
                为:P(k)*[1/(n-k+1)];
则第k+1个人的位置让别人坐了的概率为:P(k)+P(k)*[1/(n-k+1)];
即:P(k+1)=P(k+1-1)+{1/[n-(k+1-1)+1]}P(k+1-1);
综上可得100个人中任意第n个人位置被坐的概率
P(n)=P(n-1)+{1/[100-(n-1)+1]}*P(n-1);

做递归计算程序如下(相信特别的简单了吧)

//自定义头文件
#ifndef   CH_H
#define   CH_H

double   P(float);//计算在给定人数情况下最后一个人位置被坐的概率

#endif

//ch.cpp文件,定义函数double   P(float)
#include   "stdafx.h "
#include   "ch.h "

double   P(float   n)   //参数n为上飞机和位置的总数
{
if(n   ==   1)
return   (n   -   1)   /   n;
else   if(n   ==   2)
return   1   /   n;   //结束条件
else  
return   P(n   -   1)   +   (1/2)   *   P(n   -   1);   //递归调用
}

//   fool.cpp   :   Defines   the   entry   point   for   the   console   application.
//

#include   "stdafx.h "
#include   <iostream.h>
#include   "ch.h "

int   main(int   argc,   char*   argv[])
{
float   n;   //第N个人的编号吧
char   flag;
do
{
cout   < <   "请输入你要知道的总人数n:   ";
cin   > >   n;
cout   < <   endl   < <   "则最后一个人能坐到自己位置的概率是: ";
cout   < <   1   -   P(n)   < <   endl   < <   endl;;   //第N个人能坐到自己的位置的概率


cout   < <   "还要计算下一个人的概率吗?Y/N   ->   ";
cin   > >   flag;
cout   < <   endl;
}while(flag   ==   'Y '   ||   flag   ==   'y ');

return   0;
}

希望大家能和我多交流,我学得的东西很少,希望大家多多指教。小弟先谢谢了。


[解决办法]
我不管你分析得对不对,但是你这个地方错了.

double P(float n) //参数n为上飞机和位置的总数
{
if(n == 1)
return (n - 1) / n;
else if(n == 2)
return 1 / n; //结束条件
else
return P(n - 1) + (1/2) * P(n - 1); //递归调用
}

----------------------------------------------------
最后一个语句相当于 return P(n - 1); 因为(1/2) = 0;

所以你算出来的是0.5.
----------------------------------------------------
把分全给我吧.

热点排行