Double Patience UVA - 1637

17 篇文章 0 订阅
2 篇文章 0 订阅

题目传送门

题意:36张牌分成9堆,每堆4张牌,每一次可以拿走顶部两个相同点数的牌,如果有多种方法则按照等概率的随机拿,如果最后拿走了所有的牌则胜利,求胜利的概率。

思路;用一个九元组储存状态,进行记忆话搜索。

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

#define MAXN 110
#define MAXE 5
#define INF 1000000000
#define MOD 10007
#define LL long long
#define ULL unsigned long long
#define pi 3.14159

using namespace std;

double dp[MAXE][MAXE][MAXE][MAXE][MAXE][MAXE][MAXE][MAXE][MAXE];
bool vis[MAXE][MAXE][MAXE][MAXE][MAXE][MAXE][MAXE][MAXE][MAXE];
vector<char> p[MAXN];

double dfs(int num1, int num2, int num3, int num4, int num5, int num6, int num7, int num8, int num9) {
    if (vis[num1][num2][num3][num4][num5][num6][num7][num8][num9])
        return dp[num1][num2][num3][num4][num5][num6][num7][num8][num9];
    vis[num1][num2][num3][num4][num5][num6][num7][num8][num9] = true;
    int num[] = {num1, num2, num3, num4, num5, num6, num7, num8, num9};
    bool flag = false;
    double &ans = dp[num1][num2][num3][num4][num5][num6][num7][num8][num9];
    for (int i = 0; i < 9; ++i) {
        if (num[i]) {
            flag = true;
            break;
        }
    }
    if (!flag) {
        return ans = 1;
    }
    int cnt = 0;
    for (int i = 0; i < 9; ++i) {
        if (!num[i])
            continue;
        for (int j = i + 1; j < 9; ++j) {
            if (!num[j])
                continue;
            if (p[i][num[i] - 1] == p[j][num[j] - 1]) {
                cnt++;
                num[i]--;
                num[j]--;
                ans += dfs(num[0], num[1], num[2], num[3], num[4], num[5], num[6], num[7], num[8]);
                num[i]++;
                num[j]++;
            }
        }
    }
    if (ans == 0)
        return ans = 0;
    return ans = ans / (double) cnt;
}

int main() {
    std::ios::sync_with_stdio(false);
    string str1, str2, str3, str4;
    while (cin >> str1 >> str2 >> str3 >> str4) {
        memset(dp, 0, sizeof(dp));
        memset(vis, false, sizeof(vis));
        memset(p, 0, sizeof(p));
        p[0].push_back(str1[0]);
        p[0].push_back(str2[0]);
        p[0].push_back(str3[0]);
        p[0].push_back(str4[0]);
        for (int i = 1; i <= 8; ++i) {
            cin >> str1 >> str2 >> str3 >> str4;
            p[i].push_back(str1[0]);
            p[i].push_back(str2[0]);
            p[i].push_back(str3[0]);
            p[i].push_back(str4[0]);
        }
        printf("%.6f\n", dfs(4, 4, 4, 4, 4, 4, 4, 4, 4));
    }
    return 0;
}

/*
 AS 9S 6C KS
 JC QH AC KH
 7S QD JD KD
 QS TS JS 9H
 6D TD AD 8S
 QC TH KC 8D
 8C 9D TC 7C
 9C 7H JH 7D
 8H 6S AH 6H
 */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值