抽彩票

题目描述

PIPI和POPO在玩一个抽彩票的游戏,彩票箱里有n张能中奖的彩票和 m 张不能中奖的彩票。PIPI和POPO轮流抽彩票,抽取彩票采取不放回的抽取方式,PIPI先抽,如果PIPI抽到了能中奖了的彩票,那么PIPI就赢了, 游戏结束。POPO后抽,如果POPO抽到能中奖的彩票,POPO也就赢了,游戏结束。否则的话,POPO就还会从彩票箱里抽一张彩票, 不管这张彩票中了没有,POPO都会拿出来扔掉。如果彩票箱里没有彩票了,那么POPO获胜。请问你PIPI最终的胜率是多少?

输入

输入一行,一个正整数 n 和 m (0<=n,m<=1000)

输出

输出PIPI获胜的概率,结果保留4位小数。

样例输入

2 3

样例输出

0.6000

/*
概率 dp, 这里采用记忆化搜索的写法,dp[i][j]代表彩票箱中有 i 张中奖彩票,j 张不中奖彩票时 PIPI 的胜率。
那么 i等于 0 时,PIPI 胜率为 0。i 不等于 0,并且 j 等于 0 时,PIPI 胜率为 1。这样就定义了递归的边界状态。否则,dp[i][j]
将进行以下 4 种转移:
1) PIPI 抽中的中奖彩票 , 直接赢,获胜概率为 i / (i+j);
2) PIPI 抽中非中奖彩票,POPO 抽中中奖彩票,获胜概率 0;
3) PIPI 抽中非中奖彩票,POPO 抽中非中奖彩票,POPO 再抽,抽中中奖彩票,丢弃,这种情况下 PIPI 的获胜概
率为 j/(i+j) * (j-1)/(i+j-1) * i / (i+j-2) * dp[i-1][j-2];
4) PIPI 抽中非中奖彩票,POPO 抽中非中奖彩票,POPO 再抽,抽中非中奖彩票,丢弃,这种情况下 PIPI 的获胜
概率为 j/(i+j) * (j-1)/(i+j-1) * (j-2) / (i+j-2) * dp[i][j-3];
dp[i][j]为上述 4 种情况的胜率之和。 
*/
#include<bits/stdc++.h>
using namespace std;
const int N=1005;
double dp[N][N];
double dfs(int n,int m){ ///记忆化搜索 
    if(n==0) return 0; ///边界条件,当n=0时,pipi获胜的概率为 0 
    if(m==0) return 1; ///边界条件,当m=0时,pipi获胜的概率为 1 
    double& ans=dp[n][m];
    if(ans) return ans;///如果ans不为0,直接返回ans的值 
    double all=n+m;
    ans+=n/all; ///ans表示pipi获胜的概率之和 
    if(m>1){
        ans+=m/all*(m-1)/(all-1)*n/(all-2)*dfs(n-1,m-2);
    }
    if(m>2){
        ans+=m/all*(m-1)/(all-1)*(m-2)/(all-2)*dfs(n,m-3);
    }
    return ans;
}
int n,m;
int main(){
    scanf("%d%d",&n,&m);
    printf("%.4f",dfs(n,m));
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值