题目
我们来玩一个掷硬币游戏:如果第一次掷,就是正面,则你马上赢;如果第一次是背面,则游戏重新开始,你需要连续掷出两次正面才能赢。如果你在掷出两次正面朝上前丢出了一个背面,则再次重新开始,且需要掷出连续三次正面朝上。简言之:第N次游戏时,必须连续掷出N次正面朝上才能赢。
问:你最终能获胜的概率是多少?
解法一
不但得出,最终的概率P一定是一个收敛的无穷数列。所以首先的思路是,找出恰好在第N次游戏赢得概率P(N=n)P(N=n),再累加起来得到P。但是如果只是简单暴力枚举的话,发现似乎找不到规律。
P(N=1)=12P(N=1)=12
P(N=2)=18P(N=2)=18
……
直接求通项的表达式失败后,换一个角度思考,那么我们可以找通项之间的关系。我们将掷出硬币的正反序列简称为序列。要想第n+1次游戏赢,那么序列的最后一定是n+1次连续的正面,而n+1次正面前一定恰好存在是N个反面。
那么P(N=n+1)=(12)n+1bnP(N=n+1)=(12)n+1bn,bnbn所代表的意义是掷出所有恰好n个反面的总概率(其中最后一个必定是反面)。
我们不难找出bn通项之间的关系:bn+1=(1−12n+1)bnbn+1=(1−12n+1)bn;进而我们找到P(n+1)P(n+1)与P(n)P(n)之间的关系:P(n+1)=2n−12n+1P(n)P(n+1)=2n−12n+1P(n)
最终的概率问题可以转化为数列求和。
已知a0=12a0=12,通项关系为an=122n−12nan−1an=122n−12nan−1,求前n项和SnSn。
对SnSn取极限就是概率P,即P=limn→+∞SnP=limn→+∞Sn
这个级数直接求和有点困难,遂用程序计算近似值。
void countpossibilty()
{
double possibilty =0;
double p[100] = {};
p[0] = 0.5;
possibilty += p[0];
for (int i = 1; i < 100; ++i)
{
p[i] =0.5* (pow(2, i) - 1) / pow(2, i)*p[i - 1];
possibilty += p[i];
cout<< possibilty << endl;
}
}
最后的概率近似于0.7112
解法二
考虑每次失败的概率会简单很多,记PiPi为每次失败的概率,则:
第1次游戏失败的概率是P1=12P1=12
第2次游戏失败的概率是P2=1−(12)2P2=1−(12)2
……
第n次游戏失败的概率是P2=1−(12)nP2=1−(12)n
整个游戏成功的概率为limn→+∞1−∏n1(1−(12)n)limn→+∞1−∏1n(1−(12)n)
这个函数并没有直接的计算方法,用程序计算近似值。
double countpossibilty(int n)
{
if (n==100)
return 1;
return (1 - pow(0.5, n))*countpossibilty(n + 1);
}
int main()
{
cout << 1-countpossibilty(1) << endl;
system("pause");
return 0;
}
同样,最后的概率近似于0.7112
补充
将这道题目的条件稍微改动下变为:如果第掷N次后还没赢得游戏,那么必须再连续掷N+1次正面才能获胜,求最终能获胜的概率。
不难得到,整个概率应当是一个收敛的无穷数列之和。由题目条件分析可知,只有抛出次数是2n-1(n为正整数)才可能能获胜。因为如果能恰好在抛出2n次获胜,需要在第n次到2n中都为正面(共n+1次正面);然而如果第n次是正面的话,那么只需要从n到2n-1之间都是正面。这就矛盾了,所以要获胜抛出次数只能是奇数次。 恰好抛出1次获胜概率为a1=0.5,恰好抛出3次获胜概率为a2=0.125,恰好抛出5次获胜概率为1/(2ˇ4)×(1-a1),恰好抛出7次获胜概率为1/(2ˇ5)×(1-a1),恰好抛出9次获胜概率为1/(2ˇ6)×(1-a1-a2)……
这是个很复杂的数列,类似斐波那契额数列,计算后面的项需要依赖前面的项,通项应该是算不出来的,遂写了个程序算了前100项。
void countpossibilty()
{
double a[100] = {};
double s[100] = {};
a[0] = 0; a[1] = 0.5; a[2] = 0.125;
for (int i = 3; i != 100; ++i)
{
double sum = 0;
for (int j = 1; j <(i / 2); ++j)
{
sum += a[j];
}
a[i] = 1 / pow(2, i + 1)*(1 - sum);
s[i] = s[i - 1] + a[i];
cout << s[i] << endl;
}
}
得到概率近似于0.7165
409

被折叠的 条评论
为什么被折叠?



