编程之美:第四章 数字之趣 4.1金刚坐飞机问题

/*
金刚坐飞机问题:
现在有一班飞机要起飞,乘客们正准备按机票号码(1,2,3,...,N)依次排队登记,突然来了一只大猩猩。它也有飞机票,但是他插队第一个登上了飞机,
然后随意地选择了一个座位坐下了。乘客有两种反应
1其他乘客也随意坐
2如果自己位置没有被占就坐下,否则随机选择另一个位置

这两种情况下,第i个乘客(除去金刚之外)做到自己原机票位置的概率是多少。

1问题1的解法:
F(i) = 第i个乘客坐到自己原位置的概率
P(i-1)=前i-1个乘客都不坐到第i个位置的概率=前i-2个乘客都不坐到第i个位置*第i-1个乘客也不坐到第i个位置=p(i-2)*Q(i-1)
G(i)=第i个乘客选择自己位置(在P(i-1)的前提下)=1/(N-(i-1)) = 1/(N - i +1)
P(1) = 前1个乘客不做到第2个位置的概率 = (N-1)/N
Q(i)= 在前i-1个乘客不坐到第i+1个位置的前提下,第i个个乘客也不坐到第i+1个位置的概率=(N-i) /(N - (i-1)) = (N-i)/(N-i+1)
所以
F(i)=P(i-1)*G(i)=P(i-2)*Q(i-1)*G(i) = P(i-3)*Q(i-2)*Q(i-1)*G(i)= ...= G(i)     *   Q(i-1)                *    Q(i-2)               * ... *   Q(2)       *   P(1)
                                                                    =1/(N-i+1) *   (N-(i-1))/(N-(i-1)+1) *    (N-(i-2))/(N-(i-2)+1)* ... *(N-2)/(N-2+1) *   (N-1)/N
																	=1/N

问题2的解法:
按照金刚座的位置分解问题,把原问题从"第i个乘客坐在自己位置上的概率是多少" = “如果金刚坐在第n个位置上,那么第i个乘客坐在自己位置上的概率是多少”=
f(n)

现在金刚坐在了第n号位置上。如果n=1或n>i,那么第i个乘客坐在自己位置上的概率是1,(其他乘客都会选择自己的位置),如果n=i,第i个乘客没有希望坐在自己
的位置上了,如果i>n>1。当金刚坐在第n个位置的时候,第2,3,...,n-1号乘客可以做到自己的作为上,按照第n个乘客的位置继续分解问题。
如果第n个乘客选择了金刚的座位,那么第i个乘客一定坐在自己的位置上,(说白了就是金刚和被金刚占座的人互换了位置);
    第n个乘客坐在第j(n<j<=N)个作为上,就相当于金刚坐在了第j个座位。问题分解到这一步,可以合并问题解答。
	合并这个步骤,可能简单,也可能复杂,取决于分解的结果。合并的主要工具是全概率公式,即P(M) = i从1到M对P(i)*P(M/i)累乘,i表示不同的情况,P(i)表示
	发生这种情况的概率,P(M|i)表示在这种情况下时间M发生的概率。
	首先求解f(n) (1<n<i),由前面的分析可知:
	f(n) = 1/(N-n+1) * f(j) (j = 1,n+1,n+2,...,N)累乘,其中j表示第n个乘客坐的位置 = 1/(N-(n-1)) * (1 + f(n+1)+ ... + f(N)) 
	推得:f(n) = f(n+1)(1< n < i-1),因为金刚占据第n个位置,第i(i > n + 1)个乘客坐在自己位置的概率 = 金刚占据第n+1个位置,第i(i > n+1)个乘客坐在自己位置的概率
	f(j) = 如果金刚坐在第j个位置上,那么任意乘客坐在自己位置上的概率是多少
	将n=2带入f(n) = 1/(N-n+1) * [1 + f(n+1) + ... + f(N)] (1 < n < i)
	f(2) = 1/(N-1) * [1 + f(3) + f(4) + ... + f(N)]
	f(1) = 1/N * [1 + f(2) + f(3) + ... + f(N)] = 1/N * [1 + f(1)*(N-1)]
	f(n) = f(n+1) (1 < n < i-1)
	f(x) = 1 (i < x) (金刚占据了第x个位置,那么第i(i<x)个乘客坐在自己位置的概率为1)
	f(x) = 0 (i = x) (金刚占据了第x个位置,那么第i个乘客=第x个乘客坐在自己座位的概率为0)

	综上:
	计算得出f(1) = 1
	f(n) = (N-i+1)/(N-i+2),不知道如何得出的?
	f(n) = {1(n=1或i<n)
	       {(N-i+1)/(N-i+2),(1<n<i)
		   {0,(n=i)
		   那么n从1到N 对1/N * f(n) = (N-i+1)/(N-i+2)就是第i个乘客坐在自己位置上的概率

输入:
100(飞机上的座位数) 1(第i个乘客)
100 50
100 100
输出:
0.01(大家都随机坐座位,坐到自己位置的概率)  0.99(没有被占领就坐下,否则随机坐下,坐到自己位置的概率)
0.01 0.98
0.01 0.50
*/

/*
关键:
1分解问题,得到局部答案
2合并问题的解答
3 return 1.0/iTotalSeat;//随机坐能做到自己围上的概率参见公式1/N
4 return (iTotalSeat - iPeopleIndex + 1)*1.0/(iTotalSeat - iPeopleIndex + 2);//尽量有序坐,实在不行随机坐还能够坐回自己位置的概率 参见公式(N-i+1)/(N-i+2)
*/

#include <stdio.h>

double randomSeatProbability(int iTotalSeat)
{
	return 1.0/iTotalSeat;//随机坐能做到自己围上的概率参见公式1/N
}

double orderSeatProbability(int iTotalSeat,int iPeopleIndex)
{
	return (iTotalSeat - iPeopleIndex + 1)*1.0/(iTotalSeat - iPeopleIndex + 2);//尽量有序坐,实在不行随机坐还能够坐回自己位置的概率 参见公式(N-i+1)/(N-i+2)
}

void process()
{
	int iTotalSeat,iPeopleIndex;
	while(EOF != scanf("%d %d",&iTotalSeat,&iPeopleIndex))
	{
		printf("%.2f %.2f\n",randomSeatProbability(iTotalSeat),orderSeatProbability(iTotalSeat,iPeopleIndex));
	}
}

int main(int argc,char* argv[])
{
	process();
	getchar();
	return 0;
}

你可能感兴趣的:(编程之美)