越来越难的掷硬币游戏

部署运行你感兴趣的模型镜像

题目

我们来玩一个掷硬币游戏:如果第一次掷,就是正面,则你马上赢;如果第一次是背面,则游戏重新开始,你需要连续掷出两次正面才能赢。如果你在掷出两次正面朝上前丢出了一个背面,则再次重新开始,且需要掷出连续三次正面朝上。简言之:第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+1bnbnbn所代表的意义是掷出所有恰好n个反面的总概率(其中最后一个必定是反面)。
我们不难找出bn通项之间的关系:bn+1=(112n+1)bnbn+1=(1−12n+1)bn;进而我们找到P(n+1)P(n+1)P(n)P(n)之间的关系:Pn+1=2n12n+1P(n)P(n+1)=2n−12n+1P(n)

最终的概率问题可以转化为数列求和。
已知a0=12a0=12,通项关系为an=122n12nan1an=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+1n1(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

您可能感兴趣的与本文相关的镜像

GPT-SoVITS

GPT-SoVITS

AI应用

GPT-SoVITS 是一个开源的文本到语音(TTS)和语音转换模型,它结合了 GPT 的生成能力和 SoVITS 的语音转换技术。该项目以其强大的声音克隆能力而闻名,仅需少量语音样本(如5秒)即可实现高质量的即时语音合成,也可通过更长的音频(如1分钟)进行微调以获得更逼真的效果

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值