dp[i][a1][a2][a3][a4] 表示上一张牌现在还剩下i张,现在点数相同数量为1的点数数量 a1,相同数量为2的数量a2,为3的数量a3,为4的数量a4。然后用记忆化搜索即可。。。。



#include <iostream>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cmath>
#include <time.h>
#define maxn 10005
#define maxm 100005
#define eps 1e-7
#define mod 10007
#define INF 0x3f3f3f3f
#define PI (acos(-1.0))
#define lowbit(x) (x&(-x))
#define mp make_pair
//#define ls o<<1
//#define rs o<<1 | 1
//#define lson o<<1, L, mid 
//#define rson o<<1 | 1, mid+1, R
#define pii pair<int, int>
#pragma comment(linker, "/STACK:16777216")
typedef long long LL;
typedef unsigned long long ULL;
//typedef int LL;
using namespace std;
LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;}
LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;}
// head

ULL dp[6][66][66][66][66];
int a[105];
int c[105];
char s[105];
int n;

ULL dfs(int now, int a1, int a2, int a3, int a4)
{
	if(dp[now][a1][a2][a3][a4] != 0) return dp[now][a1][a2][a3][a4];
	if(a1 == 0 && a2 == 0 && a3 == 0 && a4 == 0) {
		if(now == 0) return 1;
		else return 0;
	}
	ULL ans = 0;
	if(a1) ans += dfs(0, a1-1, a2, a3, a4) * (now == 1 ? a1-1 : a1);
	if(a2) ans += dfs(1, a1+1, a2-1, a3, a4) * 2 * (now == 2 ? a2-1 : a2);
	if(a3) ans += dfs(2, a1, a2+1, a3-1, a4) * 3 * (now == 3 ? a3-1 : a3);
	if(a4) ans += dfs(3, a1, a2, a3+1, a4-1) * 4 * (now == 4 ? a4-1 : a4);	
	return dp[now][a1][a2][a3][a4] = ans;
}

void work(int _)
{
	memset(a, 0, sizeof a);
	memset(c, 0, sizeof c);
	scanf("%d", &n);
	for(int i = 1; i <= n; i++) {
		scanf("%s", s);
		int t = s[0] - '0';
		if(s[0] == 'T') t = 10;
		if(s[0] == 'J') t = 11;
		if(s[0] == 'Q') t = 12;
		if(s[0] == 'K') t = 13;
		if(s[0] == 'A') t = 1;
		c[t]++;
	}
	for(int i = 1; i <= 13; i++) a[c[i]]++;
	printf("Case #%d: %llu\n", _, dfs(5, a[1], a[2], a[3], a[4]));
}

int main(void)
{
	int _;
	scanf("%d", &_);
	for(int i = 1; i <= _; i++) work(i);
	
	return 0;
}