3139:[HNOI2013]比賽 - BZOJ

題目描述 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.
View Code
相關文章
相關標籤/搜索