递归完美解决"傻子造成的问题"

递归完美解决"傻子造成的问题"

昨天晚上快睡觉的时候在这里看到了这样的一个帖子,问题是:

"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;
}

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值