題目描述 Description
沫沫很是喜歡看足球賽,但由於沉迷於射箭遊戲,錯過了最近的一次足球聯賽。這次聯賽共N只隊伍參加,比賽規則以下:
(1) 每兩支球隊之間踢一場比賽。
(2) 若平局,兩支球隊各得1分。
(3) 不然勝利的球隊得3分,敗者不得分。
儘管很是遺憾沒有觀賞到精彩的比賽,但沫沫經過新聞知道了每支球隊的最後總得分,而後聰明的她想計算出中多少種可能的比賽狀況。
但沫沫發現當球隊較多時,計算工做量將很是大,因此這個任務就交給你了。請你計算出可能的比勝過程的數目,因爲答案可能很大,你只須要輸出答案對109+7取模的結果。
輸入描述 Input Description
第一行是一個正整數N。
接下來一行N個非負整數,依次表示各隊的最後得分。
輸入保證20%的數據知足N≤4,40%的數據知足N≤6,60%的數據知足N≤8,100%的數據知足3≤N≤10.
輸出描述 Output Description
輸入答案mod 10^9+7
樣例輸入 Sample Input
4
4 3 6 4
樣例輸出 Sample Output
3ide
其實想想,還真是那個道理,不是你不懂,是你不敢去作,不敢去想spa
每個對於一個得分序列,無論怎麼交換,都不會影響答案,因此咱們能夠用記憶化搜索,hash一下當前的狀態3d
可是這個狀態必須是i我的,兩兩之間都沒比賽的狀況code
咱們爆搜每個人的比賽狀況,而後記憶化一下,若是之前已經搜過了,就直接返回答案blog
看了題解說狀態只有40000左右,我就只開了80000的hash遊戲
1 const 2 h=30077; 3 mo=1000000007; 4 var 5 a,s:array[0..10]of longint; 6 nsum,num:array[0..80000]of int64; 7 next:array[0..80000]of longint; 8 n,ans,sum,yes,no,tot:longint; 9 c:array[0..27]of longint; 10 11 procedure init; 12 var 13 i,j,t:longint; 14 begin 15 read(n); 16 for i:=1 to n do 17 begin 18 read(a[i]); 19 inc(sum,a[i]); 20 end; 21 yes:=sum-n*(n-1); 22 no:=n*(n-1)>>1-yes; 23 for i:=n downto 2 do 24 for j:=1 to i-1 do 25 if a[j]>a[j+1] then 26 begin 27 t:=a[j]; 28 a[j]:=a[j+1]; 29 a[j+1]:=t; 30 end; 31 end; 32 33 function hash(x:int64):longint; 34 begin 35 exit(trunc(x*10007 mod h)); 36 end; 37 38 function find(x:int64):boolean; 39 var 40 i:longint; 41 begin 42 i:=hash(x); 43 while i<>0 do 44 begin 45 if num[i]=x then exit(true); 46 i:=next[i]; 47 end; 48 exit(false); 49 end; 50 51 procedure insert(s,x:int64); 52 var 53 i:longint; 54 begin 55 i:=hash(s); 56 while (num[i]<>s)and(next[i]<>0) do 57 i:=next[i]; 58 if num[i]=s then nsum[i]:=(nsum[i]+x)mod mo 59 else 60 begin 61 inc(tot); 62 next[i]:=tot; 63 num[tot]:=s; 64 nsum[tot]:=x; 65 end; 66 end; 67 68 function get(x:int64):int64; 69 var 70 i:longint; 71 begin 72 i:=hash(x); 73 while (num[i]<>x)and(next[i]<>0) do 74 i:=next[i]; 75 if num[i]=x then exit(nsum[i]) 76 else exit(0); 77 end; 78 79 function dfs(x,y:longint):int64; 80 var 81 i,j,xi,yi:longint; 82 ss:int64; 83 begin 84 if x=n then exit(1); 85 if y=x+1 then 86 begin 87 ss:=0; 88 fillchar(c,sizeof(c),0); 89 for i:=x to n do 90 inc(c[a[i]-s[i]]); 91 for i:=27 downto 0 do 92 for j:=1 to c[i] do 93 ss:=ss*28+i; 94 if find(ss) then exit(get(ss)); 95 end; 96 dfs:=0; 97 if (s[x]+(n-y+1)*3<a[x])or(s[x]+yes*3+(n-y+1-yes)<a[x]) then exit(dfs); 98 if y=n then 99 begin 100 xi:=x+1; 101 yi:=xi+1; 102 end 103 else 104 begin 105 xi:=x; 106 yi:=y+1; 107 end; 108 if yes>0 then 109 begin 110 if s[x]+3<=a[x] then 111 if (y<n)or((y=n)and(s[x]+3=a[x])) then 112 begin 113 dec(yes); 114 inc(s[x],3); 115 dfs:=(dfs+dfs(xi,yi))mod mo; 116 inc(yes); 117 dec(s[x],3); 118 end; 119 if s[y]+3<=a[y] then 120 if (y<n)or((y=n)and(s[x]=a[x])) then 121 begin 122 dec(yes); 123 inc(s[y],3); 124 dfs:=(dfs+dfs(xi,yi))mod mo; 125 inc(yes); 126 dec(s[y],3); 127 end; 128 end; 129 if no>0 then 130 if (s[x]+1<=a[x])and(s[y]+1<=a[y]) then 131 if (y<n)or((y=n)and(s[x]+1=a[x])) then 132 begin 133 dec(no); 134 inc(s[x]); 135 inc(s[y]); 136 dfs:=(dfs+dfs(xi,yi))mod mo; 137 inc(no); 138 dec(s[x]); 139 dec(s[y]); 140 end; 141 if y=x+1 then insert(ss,dfs); 142 end; 143 144 begin 145 init; 146 tot:=h; 147 write(dfs(1,2)); 148 end.