萌新求调 TLE on #2,#10
查看原帖
萌新求调 TLE on #2,#10
461359
huangrenheluogu楼主2023/8/9 17:28
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod = 1e9 + 7;
int n, a[15], s3, s1, sum, tt;
//s3,s1:记录胜负场和平局场,剪枝
map<int, int>f;//hash : 记忆化搜索(因为方案总数只与得分集合有关)
inline int Hash(int x){
	int res = x, tem[15];
	for(int i = 1; i <= n; i++) tem[i] = a[i];
	sort(tem + 1, tem + n + 1);
	for(int i = 1; i <= n; i++){
		res = res * 28 + a[i];
	}
	return res;
}
inline int dfs(int x, int y, int win, int ping){//两两逐个比赛
	int res = 0;
	if(a[x] > 3 * (n - y + 1)) return 0;
	if(y == n + 1){
		if(a[x] != 0) return 0;
		if(x == n) return 1;
		tt = Hash(x);
		if(f.count(tt)) return f[tt];
		return f[tt] = dfs(x + 1, x + 2, win, ping);
	}
	if(a[x] >= 3 && win){
		a[x] -= 3;
		win--;
		res += dfs(x, y + 1, win, ping);
		a[x] += 3;
		win++;
	}
	if(a[y] >= 3 && win){
		a[y] -= 3;
		win--;
		res += dfs(x, y + 1, win, ping);
		a[y] += 3;
		win++;
	}
	if(a[x] && a[y] && ping){
		a[x]--, a[y]--;
		ping--;
		res += dfs(x, y + 1, win, ping);
		a[x]++, a[y]++;
		ping++;
	}
	return res % mod;
}
signed main(){
	scanf("%lld", &n);
	for(int i = 1; i <= n; i++){
		scanf("%lld", &a[i]);
		sum += a[i];
	}
	s3 = sum - (n * (n - 1));
	s1 = (sum - 3 * s3) / 2;
	printf("%lld", dfs(1, 2, s3, s1));
	return 0;
}
2023/8/9 17:28
加载中...