bzoj3139: [Hnoi2013]比賽

Description

沫沫很是喜歡看足球賽,但由於沉迷於射箭遊戲,錯過了最近的一次足球聯賽。這次聯 賽共N支球隊參加,比賽規則以下:
(1) 每兩支球隊之間踢一場比賽。 (2) 若平局,兩支球隊各得1分。
(3) 不然勝利的球隊得3分,敗者不得分。
儘管很是遺憾沒有觀賞到精彩的比賽,但沫沫經過新聞知道了每隻球隊的最後總得分, 而後聰明的她想計算出有多少種可能的比勝過程。
譬若有3支球隊,每支球隊最後均積3分,那麼有兩種可能的狀況:
 可能性1    可能性2
球隊  A  B  C  得分   球隊 A  B  C  得分
A        -  3  0  3             A     -  0  3  3
B        0  -  3  3             B    3  -  0  3
C        3  0  -  3            C    0  3  -  3
但沫沫發現當球隊較多時,計算工做量將很是大,因此這個任務就交給你了。請你計算 出可能的比勝過程的數目,因爲答案可能很大,你只須要輸出答案對109+7取模的結果node

Input

第一行是一個正整數N,表示一共有N支球隊。接下來一行N個非負整數,依次表示各隊的最後總得分。ios

輸入保證20%的數據知足N≤440%的數據知足N≤660%的數據知足N≤8100%的數據知足3≤N≤10且至少存在一組解。git

Output

僅包含一個整數,表示答案對10^9+7取模的結果spa

Sample Input

4
4 3 6 4

Sample Output

3
 
 
題解:http://blog.csdn.net/thy_asdf/article/details/50418791
code:
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #define maxn 12
 7 #define mod 1000000007
 8 #define base1 31
 9 #define mod1 99997
10 #define base2 97
11 #define mod2 480881
12 #define maxnode 1000000
13 using namespace std;
14 char ch;
15 bool ok;
16 void read(int &x){
17     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
18     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
19     if (ok) x=-x;
20 }
21 int n,list[maxn];
22 struct state{
23     int tot,hash[mod1],pre[maxnode],key[maxnode],ans[maxnode];
24     int find(int st,int n){
25         int u=st,v=st;
26         for (int i=1;i<=n;i++) u=(u*base1+list[i]+1)%mod1;
27         for (int i=1;i<=n;i++) v=(v*base2+list[i]+1)%mod2;
28         for (int p=hash[u];p;p=pre[p]) if (key[p]==v) return ans[p];
29         return -1;
30     }
31     void add(int st,int n,int tmp){
32         int u=st,v=st;
33         for (int i=1;i<=n;i++) u=(u*base1+list[i]+1)%mod1;
34         for (int i=1;i<=n;i++) v=(v*base2+list[i]+1)%mod2;
35         pre[++tot]=hash[u],hash[u]=tot,key[tot]=v,ans[tot]=tmp;
36     }
37 }S;
38 int dfs(int st,int n){
39     if (n==1&&!list[n]) return 1;
40     if (n==1&&list[n]) return 0;
41     if (st==n&&list[n]) return 0;
42     if (st==n&&!list[n]) return dfs(1,n-1);
43     if (st==1){
44         int sum=0;
45         for (int i=1;i<=n;i++) sum+=list[i];
46         if (sum<n*(n-1)||sum>3*n*(n-1)/2) return 0;
47     }
48     if (st==1) sort(list+1,list+n+1);
49     int ans;
50     if (st==1){
51         ans=S.find(st,n);
52         if (ans!=-1) return ans;
53     }
54     int res[maxn];
55     if (!list[n]){
56         for (int i=st;i<n;i++) if (list[i]<3) return 0;
57         for (int i=1;i<=n;i++) res[i]=list[i];
58         for (int i=st;i<n;i++) list[i]-=3;
59         ans=dfs(1,n-1);
60         for (int i=1;i<=n;i++) list[i]=res[i];
61         if (st==1) S.add(st,n,ans);
62         return ans;
63     }
64     for (int i=1;i<=n;i++) res[i]=list[i];
65     ans=0;
66     if (list[n]-1<=(n-st-1)*3&&list[st]>=1&&list[n]>=1) list[n]--,list[st]--,ans+=dfs(st+1,n),ans%=mod;
67     for (int i=1;i<=n;i++) list[i]=res[i];
68     if (list[n]>=3) list[n]-=3,ans+=dfs(st+1,n),ans%=mod;
69     for (int i=1;i<=n;i++) list[i]=res[i];
70     if (list[n]<=(n-st-1)*3&&list[st]>=3) list[st]-=3,ans+=dfs(st+1,n),ans%=mod;
71     for (int i=1;i<=n;i++) list[i]=res[i];
72     if (st==1) S.add(st,n,ans);
73     return ans;
74 }
75 int main(){
76     read(n);
77     for (int i=1;i<=n;i++) read(list[i]);
78     printf("%d\n",dfs(1,n));
79     return 0;
80 }
相關文章
相關標籤/搜索