这道题居然没有人写题解?
这道题的难点是在于如何保存扑克牌的状态,直接记录扑克牌的花色或者面值是不行的。
仔细想想,记录面值和花色好像没有必要,题目只要求一张牌与旁边的面值不同
所以我就设$f[有1种花色的牌][有2种花色的牌][有3种花色的牌][有4种花色的牌][上一个放的是哪一种]$
状态转移很简单,不多说
#pragma GCC optimize("Ofast")
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef unsigned long long ULL;
int n, a[14], b[4], mp[400];
ULL f[14][14][14][14][5];
bool bk[14][14][14][14][5];
ULL dfs(int x, int y, int l, int r, int last) {
if (!x && !y && !l && !r) return 1;
if (bk[x][y][l][r][last] != 0) return f[x][y][l][r][last];
ULL ans = 0;
if (x) ans += (ULL)(x - (last == 1)) * dfs(x - 1, y, l, r, 0);
if (y) ans += (ULL)(y - (last == 2)) * 2 * dfs(x + 1, y - 1, l, r, 1);
if (l) ans += (ULL)(l - (last == 3)) * 3 * dfs(x, y + 1, l - 1, r, 2);
if (r) ans += (ULL)r * 4 * dfs(x, y, l + 1, r - 1, 3);
bk[x][y][l][r][last] = 1;
return f[x][y][l][r][last] = ans;
}
int main() {
for (int i = 2; i <= 9; i++) mp['0' + i] = i;
mp['A'] = 1, mp['T'] = 10, mp['J'] = 11, mp['Q'] = 12, mp['K'] = 13;
int T; cin >> T;
for (int ki = 1; ki <= T; ki++) {
scanf("%d", &n);
char s[5];
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
for (int i = 1; i <= n; i++) {
scanf("%s", s);
a[mp[s[0]]]++;
}
for (int i = 1; i <= 13; i++)
if (a[i]) b[a[i] - 1]++;
printf("Case #%d: %llu\n", ki, dfs(b[0], b[1], b[2], b[3], 0));
}
return 0;
}
有点像数位dp了
orz
orz
orz
Orz
Orz
orz
Orz
Orz