\ (n \) teams competition, two teams race each time. If the two teams tie, then each scored \ (1 \) points; otherwise, the winning team get \ (3 \) points, defeated the team get \ (0 \) points. Given the team's final score, find how many possible score table.
Solution
Search + vigorously pruning
First enumeration 1v2,1v3, ..., 1vN, and then enumerate 2v3,2v4, ..., 2vN, and so on
In order to accelerate the owners in accordance with the score from small to large
Then use the hash memory of what
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 10;
const int mod = 11451419198107;
int a[N],n;
map<int,int> h;
int gethash(int i,int j) {
int res = i*17+j;
for(int i=1;i<=n;i++) ((res*=17)+=a[i])%=mod;
return (res+mod)%mod;
}
int dfs(int i,int j) {
if(a[i]<0) return 0;
if(j>n) {
if(a[i]) return 0;
++i, j=i+1;
}
if(h.find(gethash(i,j))!=h.end()) {
return h[gethash(i,j)];
}
int tmp=0;
if(i==n && a[i]==0) ++tmp;
else {
if(a[i]>0 && a[j]>0) {
--a[i]; --a[j];
tmp += dfs(i,j+1);
++a[i]; ++a[j];
}
if(a[i]>2) {
a[i]-=3;
tmp += dfs(i,j+1);
a[i]+=3;
}
if(a[j]>2) {
a[j]-=3;
tmp += dfs(i,j+1);
a[j]+=3;
}
}
h[gethash(i,j)]=tmp;
return tmp;
}
signed main() {
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+n+1);
cout<<dfs(1,2)<<endl;
}