【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\n",dp[4][4][4][4][4][4][4][4][4]);  
    }  
}  

 

posted @ 2018-10-30 16:33  WJEMail  阅读(234)  评论(0编辑  收藏  举报