Double Patience UVA - 1637

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

思路:记忆化搜索,学习了一种很棒的写法参考

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
#define mod 1000000007;
using namespace std;
//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
const int maxn = 20 + 2;
char card[10][5][3];
map<vector<int>,double> d;
bool init()
{
    for(int i = 0; i < 9; i++)
    {
        for(int j = 0; j < 4; j++)
            if(scanf("%s",card[i][j]) != 1) return false;
    }
    return true;
}
double dfs(int res,vector<int> & num)
{
    if(!res) return 1;
    if(d.count(num) != 0) return d[num];
    double sum = 0,tot = 0;
    for(int i = 0;i < 9;i++)
    {
        if(num[i] == 0) continue;
        char c = card[i][num[i] - 1][0];
        for(int j = i + 1;j < 9;j++)
        {
            if(num[j] == 0) continue;
            if(c == card[j][num[j] - 1][0])
            {
                tot++,num[i]--,num[j]--;
                sum += dfs(res - 1,num);
                num[i]++,num[j]++;

            }
        }
    }
    if(!tot) return d[num] = 0;
    else return d[num] = sum / tot;
}
int main()
{
    while(init())
    {
        d.clear();
        vector<int> num(9,4);
        printf("%.6f\n",dfs(18,num));
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sgsyacm/article/details/87099141
今日推荐