Description
Little A is building blocks. There are n locations where small A can be used, with an initial height of 0. Each time a building block, small a will be selected to have the same height of the interval [a. B], then add one to the height of all the bricks on the position [a+1..b-1]. Unfortunately, little a after the building blocks, small a naughty brother will be a number of several positions on the building blocks were knocked down. Little a wants to know how his original building blocks are placed, so he turned to you and asked you to tell him how many possible pendulum methods there were.
Input
The first behavior is a positive integer n, which indicates that small a has n positions.
The second line has n spaces separated by the integer Hi, which represents the height of the bricks at the first position. 1 means that the building blocks in this position have been knocked down.
Output
The only line that output includes the results of the possible pendulum mod 1,000,000,007.
Sample Input
Input 1:
3
-1 2-1
Input 2:
-1-1-1
Input 3:
6
-1-1-1 2-1-1
Sample Output
Output 1:
0
Output 2:
2
Output 3:
3
Data Constraint
For 50% of data 1<=n<=1000-1<=hi<=1000
For 80% of data 1<=n<=10000
For 100% of data 1<=n<=20000-1<=hi<=10000
Analysis:
(hydrolysis):
Set F[I,J] is the number of I, the height of the program number of J, there are
F[i,j]=sum (F[i-1,j-1],f[i-1,j],f[i-1,j+1])
If A[i] is not destroyed, then the state outside of F[i,a[i]] is not legal.
Violent running aside, will be more than a little when. Change the MoD to 10 times to take the MoD once and it will not time out.
(positive solution): For every two points with a definite height, that is, a[i]≠-1 (or 0 at both ends), consider the number of scenarios in the middle.
Set A[i] and a[j]≠-1, then
For collections
{a[i],a[i+1],a[i+2],...... a[j]}
Because the difference between the two adjacent numbers does not exceed 1, the collection is obtained
{A[i+1]-a[i],a[i+2]-a[i],...... a[j]-a[j-1]}
The value of each element of this collection may only be -1,0,1 and the sum=a[j]-a[i of these elements].
If sum>0, delete the sum of 1, the remaining elements and 0;
If sum<0, delete the |sum|. 1, remaining original and 0;
In fact, these two states are equivalent.
At this point we get a set of and 0.
Set I to J in the middle there are M elements, of which 1 have X, then 1 has x, 0 is there (m-2x-sum) (in fact, this is not important).
The number of programs is C (m,sum+x) *c (m-sum-x,x)
{There are m slots in the middle, 1 have sum+x; for the remaining m-sum-x positions, 1 has X, the remaining positions are 0, the scheme is obviously 1, and the result of multiplication is not changed}
We should preprocess the n! first. (Of course to take the MoD), and then each operation has a combination of numbers, thought to be divided by some already mod number, to preprocess the inverse of the n!. Because mod p (p is prime), it can be obtained by Fermat theorem or Euler theorem.
(n!) ^ ( -1) = (n!) ^ (p-2)
Code (hydrolysis):
Const
modd=1000000007;
var
f:array [0..1,-1..20001] of int64;
A,max:array [0..20001] of Longint;
N,i,j,x,s,t,m,y:longint;
Begin
Assign (input, ' brick.in ');
Assign (output, ' brick.out ');
Reset (input);
Rewrite (output);
READLN (n);
For I:=1 to n do
read (A[i]);
If A[1]>0 then
begin
Writeln (0);
Close (input);
Close (output);
Exit;
End;
M:=n Div 2+1;
For I:=1 to N does
if I<m then max[i]:=i-1 else max[i]:=n-i;
x:=0;
F[x,0]:=1;
For i:=2 to n do
begin
y:=x;
X:=1-x;
Fillchar (F[x],sizeof (f[x]), 0);
If A[i]=-1 then
begin
If I mod 10=0 then for
j:=0 to Max[i] do
f[x,j]:= (f[y,j-1]+f[y,j]+f[y,j+1]) mod Modd
Else for
j:=0 to Max[i] do
f[x,j]:=f[y,j-1]+f[y,j]+f[y,j+1];
End
Else
f[x,a[i]]:= (f[y,a[i]-1]+f[y,a[i]]+f[y,a[i]+1]) mod modd;
End;
Writeln (f[x,0] mod modd);
Close (input);
Close (output);
End.
Code (positive solution) (By:jzoj a great God, I only reprint):
Const MO=1000000007;
var n,i,j,k,l,h:longint;
A:array[1..20000]of Longint;
Jc,ny:array[0..20000]of Longint;
Ans,tot:longint;
function KSM (x,y:longint): Longint;
Begin if Y=1 then exit (x);
KSM:=KSM (x,y>>1); Ksm:=int64 (KSM) *ksm mod mo;
If Y and 1=1 then Ksm:=int64 (KSM) *x mod mo;
End
Function C (a,b:longint): Longint;
Begin if A>b then exit (0);
Exit (Int64 (Jc[b]) *ny[a]mod mo*ny[b-a]mod mo);
End
Begin assign (input, ' brick.in '); reset (input);
Assign (output, ' brick.out '); rewrite (output);
READLN (n); for i:=1-n do read (A[i]);
Jc[0]:=1;for i:=1 to N do Jc[i]:=int64 (jc[i-1]) *i mod mo;
NY[N]:=KSM (jc[n],mo-2); i:=n-1 downto 0 do Ny[i]:=int64 (ny[i+1]) * (i+1) mod mo;
if (a[1]>0) or (a[n]>0) then begin Writeln (0); halt;
End
A[1]:=0;a[n]:=0;i:=1;j:=1;ans:=1;
While I<n does Begin Inc (i); if A[i]>-1 then BEGIN Tot:=0;h:=abs (A[i]-a[j]);
For k:=0 to I-j-h do Begin L:=i-j-k;if (l+h) and 1=1 then continue;
Tot:= (Tot+int64 (C (k,i-j)) * (c ((l+h) >>1,l)-C ((l+a[i]+a[j]+2) >>1,l) mod mo+mo) mod mo;
End
Ans:=int64 (tot) *ans mod mo;j:=i;
End
End
Writeln (ANS); End.