UVA11427 Expect the Expected

本文探讨了一个关于纸牌游戏的数学问题,玩家在一个晚上玩纸牌直到获胜比率超过设定值p才会停止。通过动态规划的方法求解玩家平均玩多少个晚上的期望值,并给出了一段C++代码实现。

每天晚上你都玩纸牌游戏,如果第一次就赢了就高高兴兴地去睡觉,如果输了就继续玩。假设每盘游戏你获胜地概率都是p,且各盘游戏的输赢都是独立的。你是一个固执的完美主义者,因此会一直玩到当晚获胜局面的比例严格大于p时才停止,然后高高兴兴地去睡觉。当然,晚上的时间有限,最多只能玩n盘游戏,如果获胜比例一直不超过p的话,你只能垂头丧气地去睡觉,以后再也不玩纸牌了。你的游戏是计算出平均情况下,你会玩多少个晚上的纸牌。

设一局胜率为p,则败率为q=1-p
第一步:求单一一天能达成目标快快乐乐去睡觉的概率,设为P

第二步:求该游戏能玩几天的期望,即无穷级数  $\sum\limits_{i=1}^\infty i*P^{i-1}*(1-P)$,可以发现这个无穷级数等于$\frac {1} {1-P}$

问题是P怎么求,我一直在想P关于n,p的数学表达式,想不出来,看了题解发现这种题是dp

设单一一天目标未达成概率为Q,即Q=1-P,如果目标未达成,他必玩了n局,而且如果设总共胜了x局,那么必须$\frac {x} {n} \leqslant p$,所有胜x局的局面都未达成目标,他们的出现概率之和即为Q
设dp[i,j]表示玩了i局胜了j局的‘目标未达成的’局面出现的概率(注:我们要求的是目标未达成的局面出现的概率,而目标未达成的局面的前一个局面一定也是目标未达成的局面),即这里dp的‘局面’全部都是满足$\frac {j} {i} \leqslant p$的局面,则转移方程为dp[i,j]=dp[i-1,j]*q+dp[i-1,j-1]*p

最后Q即为dp[n,x]之和,输出1/Q就完事了

#include<bits/stdc++.h>
using namespace std;    
int N,a,b,n;
double p,Q;
double dp[100+10][100+10];
int main(){
    cin>>N;
    for(int t=1;t<=N;t++){
        scanf("%d/%d%d",&a,&b,&n);
        p=(double)a/(double)b;
        for(int i=0;i<=n;i++)
            for(int j=0;j<=n;j++)
                dp[i][j]=0;  
        dp[1][0]=1.0-p;   //边界 
        //求当晚失败概率Q 
        //dp[i,j]  局面i局中赢了j局'出现'的概率 注意:j/i<=p
        //dp[i,j]=dp[i-1,j]*q+dp[i-1,j-1]*p  注意:j/i<=p要一直成立
        //边界 dp[1,0] 
        Q=0;
        for(int i=2;i<=n;i++){
            for(int j=0;(double)j<=p*(double)i;j++){
                dp[i][j]+=(p*dp[i-1][j-1]+(1.0-p)*dp[i-1][j]);
            }
        }
        for(int i=0;(double)i<=p*(double)n;i++){
            Q+=dp[n][i];
        }
        int ans=1.0/Q;
        printf("Case #%d: %d\n",t,ans);
    }
    return 0;
}

 那么这个P到底有没有数学表达式呢??

转载于:https://www.cnblogs.com/spzeno/p/11215340.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值