• 扑克牌


    扑克牌

    题目大意,即有54张牌(有大王小王),询问,随机从中抽牌不放回,问得到A张黑桃、B张红桃、C张梅花、D张方块所需抽牌的牌数的期望数,注意抽到的大王和小王可以作为任意一种花色的牌对待,但是所作为的方案,要使最终的期望最小,0<=A,B,C,D<=15。

    显然为期望题,显然顺推记概率太麻烦,考虑倒推,于是设(f[a][b][c][d][x][y])已经 抽出a张黑桃,b张红桃,c张梅花,d张方块,大小王状态为x,y
    (0表示未抽到,1表示作为黑桃,2红桃,3梅花,4方块) 到达目标状态的数学期望 ,设(sum=a+b+c+d+(x>0)+(y>0)),根据递推套路,我们不难有

    [f[a][b][c][d][x][y]=f[a+1][b][c][d][x][y] imesfrac{13-a}{54-sum}+ ]

    [f[a][b+1][c][d][x][y] imesfrac{13-b}{54-sum}+f[a][b][c+1][d][x][y] imesfrac{13-c}{54-sum}+ ]

    [f[a][b][c+1][d][x][y] imesfrac{13-c}{54-sum}+f[a][b][c][d+1][x][y] imesfrac{13-d}{54-sum}+ ]

    [frac{1}{54-sum} imes min_{i=1,!x}^4(f[a][b][c][d][i][y]) ]

    [frac{1}{54-sum} imes min_{i=1,!x}^4(f[a][b][c][d][x][i])+1 ]

    再根据所需要的牌数作为边界,注意大小王的影响,故边界不简简单单地为(f[A][B[C][D][?][?]=0),答案不难得知为(f[0][0][0][0][0][0]),根据递推方程转移即可。

    参考代码:

    #include <iostream>
    #include <cstdio>
    #define il inline
    #define ri register
    #define db double
    #define exact 0.001
    using namespace std;
    int A,B,C,D;
    db dp[14][14][14][14][5][5];
    il db dfs(int,int,int,int,int,int);
    il bool check(int,int,int,int,int,int);
    template<class free>il free Min(free,free);
    int main(){
        int check(0);
        scanf("%d%d%d%d",&A,&B,&C,&D);
        if(A>13)check+=A-13;if(B>13)check+=B-13;
        if(C>13)check+=C-13;if(D>13)check+=D-13;
        if(check>2)puts("-1.000");
        else printf("%.3lf",dfs(0,0,0,0,0,0));
        return 0;
    }
    template<class free>
    il free Min(free a,free b){
        return a<b?a:b;
    }
    il db dfs(int a,int b,int c,int d,int x,int y){
        db &ans=dp[a][b][c][d][x][y];
        if(ans>exact)return dp[a][b][c][d][x][y];
        if(check(a,b,c,d,x,y))return 0;
        int rest(54-(a+b+c+d+(x>0)+(y>0)));
        if(a<13)ans+=dfs(a+1,b,c,d,x,y)*(13-a)/rest;
        if(b<13)ans+=dfs(a,b+1,c,d,x,y)*(13-b)/rest;
        if(c<13)ans+=dfs(a,b,c+1,d,x,y)*(13-c)/rest;
        if(d<13)ans+=dfs(a,b,c,d+1,x,y)*(13-d)/rest;
        if(!x)ans+=Min(Min(dfs(a,b,c,d,1,y),dfs(a,b,c,d,2,y)),
                        Min(dfs(a,b,c,d,3,y),dfs(a,b,c,d,4,y)))/rest;
        if(!y)ans+=Min(Min(dfs(a,b,c,d,x,1),dfs(a,b,c,d,x,2)),
                        Min(dfs(a,b,c,d,x,3),dfs(a,b,c,d,x,4)))/rest;
        return ++ans;
    }
    il bool check(int a,int b,int c,int d,int x,int y){
        if(x==1)++a;else if(x==2)++b;else if(x==3)++c;else if(x==4)++d;
        if(y==1)++a;else if(y==2)++b;else if(y==3)++c;else if(y==4)++d;
        if(a>=A&&b>=B&&c>=C&&d>=D)return true;else return false;
        
    }
    
  • 相关阅读:
    Flume
    nodejs中npm工具自身升级
    Nodejs v4.x.0API文档学习(1)简介
    nodejs设置NODE_ENV环境变量(1)
    nodejs使用express4框架默认app.js配置说明
    mongodb2.X添加权限
    javascript中new Date浏览器兼容性处理
    Android Studio中文组(中文社区)
    Javascript日期处理类库Moment.js
    android 按两次返回键退出应用
  • 原文地址:https://www.cnblogs.com/a1b3c7d9/p/10812355.html
Copyright © 2020-2023  润新知