题意: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
*/