• 【UVA1637】纸牌游戏


    题意

    36张牌分成9堆,每堆4张牌。每次可以拿走某两堆顶部的牌,但需要点数相同。如果有 多种拿法则等概率的随机拿。例如,9堆顶部的牌分别为KS, KH, KD, 9H, 8S, 8D, 7C, 7D, 6H,则有5种拿法(KS,KH), (KS,KD), (KH,KD), (8S,8D), (7C,7D),每种拿法的概率均为1/5。 如果最后拿完所有牌则游戏成功。按顺序给出每堆牌的4张牌,求成功概率。

    分析

    为啥一张牌是两个字符组成??这什么奇怪的牌??按照题面给的例子就是说,只要第一个字符相同就OK了吧。。

    于是我们考虑预处理存每一堆牌的每一位的花色的状态,然后因为牌的数量很少,开个九维的dp来存状态,用记忆化搜索转移。

    其实转移方法就很简单了,在dfs里枚举相同的两堆堆顶,然后把这两堆顶部的牌取走作为下一个状态,计算一共有多少方案数以及这些方案数成功的概率之和。

    那么本状态成功的概率就是 ∑可达的下一个状态成功概率 ÷ 可达的方案数

    而边界就是全部取光的状态的成功概率为100%

    代码

    #include<bits/stdc++.h>  
    using namespace std;  
    #define N 6  
    int a[15][15];  
    char s[15][15];  
    int vis[N][N][N][N][N][N][N][N][N];  
    double dp[N][N][N][N][N][N][N][N][N];  
      
    inline void init()  
    {  
        memset(dp,0,sizeof(dp));  
        memset(vis,0,sizeof(vis));  
    }  
      
    inline double dfs(int p1,int p2,int p3,int p4,int p5,int p6,int p7,int p8,int p9)  
    {  
        if(vis[p1][p2][p3][p4][p5][p6][p7][p8][p9])return dp[p1][p2][p3][p4][p5][p6][p7][p8][p9];  
        vis[p1][p2][p3][p4][p5][p6][p7][p8][p9]=1;  
        int ok=1,tot=0,tmp[10]={0,p1,p2,p3,p4,p5,p6,p7,p8,p9};  
        for(int i=1;i<=9;i++)  
            if(tmp[i]){ok=0;break;}  
        if(ok)return dp[p1][p2][p3][p4][p5][p6][p7][p8][p9]=1.0;  
        double possibility=0.0;  
        for(int i=1;i<=9;i++)  
            for(int j=i+1;j<=9;j++)  
                if(tmp[j]&&tmp[i]&&a[i][tmp[i]]==a[j][tmp[j]])  
                {  
                    tmp[i]--,tmp[j]--;tot++;  
                    possibility+=dfs(tmp[1],tmp[2],tmp[3],tmp[4],tmp[5],tmp[6],tmp[7],tmp[8],tmp[9]);  
                    tmp[i]++,tmp[j]++;  
                }  
        if(tot)dp[p1][p2][p3][p4][p5][p6][p7][p8][p9]=possibility/(1.0*tot);  
        return dp[p1][p2][p3][p4][p5][p6][p7][p8][p9];  
    }  
      
    int main()  
    {  
        while(~scanf("%s%s%s%s",s[1],s[2],s[3],s[4]))  
        {  
            init();  
            for(int j=1;j<=4;j++)a[1][j]=s[j][0]-'0';  
            for(int i=2;i<=9;i++)  
                for(int j=1;j<=4;j++)  
                {  
                    scanf("%s",s[j]);  
                    a[i][j]=s[j][0]-'0';  
                }     
            dfs(4,4,4,4,4,4,4,4,4);  
            printf("%.6lf
    ",dp[4][4][4][4][4][4][4][4][4]);  
        }  
    }  
  • 相关阅读:
    Checking Types Against the Real World in TypeScript
    nexus pip proxy config
    go.rice 强大灵活的golang 静态资源嵌入包
    几个golang 静态资源嵌入包
    rpm 子包创建学习
    Rpm Creating Subpackages
    ava 类似jest snapshot 功能试用
    ava js 测试框架基本试用
    The Architectural Principles Behind Vrbo’s GraphQL Implementation
    graphql-compose graphql schema 生成工具集
  • 原文地址:https://www.cnblogs.com/NSD-email0820/p/9877503.html
Copyright © 2020-2023  润新知