哗啦啦村的日常游戏(一)抓个球

Problem Description

唐老师和狗哥在玩哗啦啦村的日常游戏——抓个球。
在袋子里有w个白球,b个黑球。
唐老师和狗哥轮流从袋子里抓球,谁先抓到白球谁就胜利。
但是,令唐老师和狗哥没想到的是,小彭玉居然来捣乱了!
每当唐老师和狗哥一回合抓球结束后(各抓取一个球),小彭玉会偷偷的抓取一个球走。
那么这时候,问题来了,当唐老师先手的时候,唐老师获胜的概率是多少呢?
假设所有抓球都是随机的。
Input

只有两个数字 w和b w<=1000 b<=1000
Output

输出唐老师赢的概率 保留9位小数
Sample Input

1 3
Sample Output

0.500000000

第一次就抓到了,或者没抓到,他也没抓到,第三个人偷白或者黑球,方程就是
f[x][y]=x/(x+y)+a*f[x-1][y-2]+b*f[x][y-3];
a,b为系数,具体的还要考虑到边界以及y的特判。
之前没有使用记忆化搜索,玩死我了- -,我加了一个数组来标记是否访问过,其实如果方便取哨兵值的时候,可以统一赋值一个哨兵值判断。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
int leap[1005][1005];
double dp[1005][1005];
double f(long long x,long long y)
{
    double ans=x*1.0/(x+y);
    if(y>=3)
    {
        if(!leap[x][y-3])
        {
            leap[x][y-3]=1;
            dp[x][y-3]=f(x,y-3);
        }
        ans=ans+dp[x][y-3]*y*(y-1)*(y-2)/((x+y)*(x+y-1)*(x+y-2));
        if(!leap[x-1][y-2])
        {
            leap[x-1][y-2]=1;
            dp[x-1][y-2]=f(x-1,y-2);
        }
        ans=ans+dp[x-1][y-2]*x*y*(y-1)/((x+y)*(x+y-1)*(x+y-2));
        return ans;
    }
    else if(y==2)
    {
        if(!leap[x-1][y-2])
        {
            leap[x-1][y-2]=1;
            dp[x-1][y-2]=f(x-1,y-2);
        }
        ans=ans+dp[x-1][y-2]*x*y*(y-1)/((x+y)*(x+y-1)*(x+y-2));
        return ans;
    }
    else if(y==1)
    {
        return ans;
    }
}
int main()
{
    long long i, j, m, n, t,w,b,x,y;
     double ans;
     cin>>w>>b;
     memset(dp,0,sizeof(dp));
     memset(leap,0,sizeof(leap));
     for(i=1;i<=w;i++)
     {
        dp[i][0]=1;
        leap[i][0]=1;
     }
     for(i=0;i<=b;i++)
     {
        dp[0][i]=0;
        leap[0][i]=1;
     }
     leap[w][b]=1;
     ans=f(w,b);

     printf("%.9lf",ans);
     cout<<endl;
     return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值