• 例10-12 *uva1637(概率dp)


    题意:36张扑克,平分成9摞,两张数字一样的可以拿走,每次随机拿两张,问能拿光的概率。
    思路:
    直接用搜索,表示出每摞剩余的牌数,然后利用全概率公式即可(P(A) = p(A|b1)*p(b1)+.....+p(A|bn)*p(bn))


    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    typedef long long ll;
    using namespace std;
    int p[10];
    int num[9][5];
    double dp[5][5][5][5][5][5][5][5][5];       //不同状态时的概率
    int vis[5][5][5][5][5][5][5][5][5];         //是否已经搜过
    char t1[4],t2[4],t3[4],t4[4];
    
    double dfs(int x1,int x2,int x3,int x4,int x5,int x6,int x7,int x8,int x9)
    {
        if(vis[x1][x2][x3][x4][x5][x6][x7][x8][x9])
            return dp[x1][x2][x3][x4][x5][x6][x7][x8][x9];
        vis[x1][x2][x3][x4][x5][x6][x7][x8][x9] = 1;
        int top[10] = {x1,x2,x3,x4,x5,x6,x7,x8,x9};
        int flag = 0;
        for(int i = 0; i < 9; i++)            //判断是否已经取完
        {
            if(top[i])
            {
                flag = 1;
                break;
            }
        }
        if(!flag )
            return  dp[x1][x2][x3][x4][x5][x6][x7][x8][x9] = 1.0;
        int pnum = 0;
        double sum = 0.0;         //当前情况往下取成功的概率
        for(int i = 0; i < 9; i ++)
        {
            for(int j = i+1; j < 9 && top[i] != 0; j++)
            {
                if(num[i][top[i]] == num[j][top[j]])
                {
                    top[i]--;
                    top[j]--;
                    pnum++;                //当前情况下有多少种取法
                    sum += dfs(top[0],top[1],top[2],top[3],top[4],top[5],top[6],top[7],top[8]);   
                    top[i]++;
                    top[j]++;
                }
            }
        }
        if(sum > 0)
            dp[x1][x2][x3][x4][x5][x6][x7][x8][x9] =(sum/(1.0*pnum));
        return dp[x1][x2][x3][x4][x5][x6][x7][x8][x9];
    }
    
    int main()
    {
        while(scanf("%s%s%s%s",t1,t2,t3,t4) != EOF)
        {
            num[0][1] = t1[0];
            num[0][2] = t2[0];
            num[0][3] = t3[0];
            num[0][4] = t4[0];
            for(int i = 1; i< 9; i++)
            {
                scanf("%s%s%s%s",t1,t2,t3,t4);
                num[i][1] = t1[0];
                num[i][2] = t2[0];
                num[i][3] = t3[0];
                num[i][4] = t4[0];
            }
            memset(vis,0,sizeof(vis));
            memset(dp,0,sizeof(dp));
            dfs(4,4,4,4,4,4,4,4,4);
            printf("%.6lf
    ",dp[4][4][4][4][4][4][4][4][4]);
        }
        return 0;
    }
    

      

  • 相关阅读:
    AX 利用windows粘贴板功能实现批量数据快速导出EXCEL
    在ax中怎么对enum类型循环取其中每一个值
    vba 快速定位当前EXCEL最后一栏
    在AX4.0中使用C#脚本的实现
    悟透javascript
    SIGAI机器学习第四集 基本概念
    SIGAI机器学习第十七集 线性模型1
    胸小肌的重要性
    SIGAI机器学习第十六集 支持向量机3
    英语听力
  • 原文地址:https://www.cnblogs.com/Przz/p/5409711.html
Copyright © 2020-2023  润新知