题目
http://172.16.0.132/senior/#contest/show/2061/3
小结
这题竟然是dp!
我们设f[i,j]表示到第i个的高度为j的方案数。
那么我们就可以知道,f[i,j]=f[i-1,j-1]+f[i-1,j]+f[i-1,j+1];但是我们j要枚举,于是我们就看j能够枚举到多少。我们知道 每个点,肯定要不比上一个多1,要不一样,要不比上一个少1。所以我们就可以预处理出所有位置最高的高度,比如说,n=8,那么我们知道h[1]和h[n]都是等于0的,所以n=8时就是0,1,2,3,3,2,1,0.最后,我们就可以这样很轻松的实现了,但是会T。
我们考虑优化,因为所有的都是要mod 1000000007 的,但这样mod会很慢,所以我们考虑每20次mod一次,这样就可以使时间得到优化。就A啦~
var
n,m,i,k,j,l1,l2:longint;
h,max:array[0..20000]of longint;
f:array[0..1,-1..20001]of int64;
begin
assign(input,'brick.in');reset(input);
assign(output,'brick.out');rewrite(output);
readln(n);
for i:=1 to n do
read(h[i]);
if n mod 2=0 then
begin
for i:=2 to n div 2 do
max[i]:=max[i-1]+1;
max[n div 2+1]:=max[n div 2];
for i:=n div 2+2 to n do
max[i]:=max[i-1]-1;
end
else
begin
for i:=2 to n div 2+1 do
max[i]:=max[i-1]+1;
for i:=n div 2+2 to n do
max[i]:=max[i-1]-1;
end;
if h[1]>0 then
begin
writeln(0);
halt;
end;
f[1,0]:=1;
h[1]:=0;
h[n]:=0;
l1:=1;
for i:=2 to n do
begin
k:=0;
if i mod 20=0 then k:=1;
l1:=i mod 2;
l2:=(i-1) mod 2;
if h[i]=-1 then
begin
for j:=0 to max[i] do
begin
if k=1 then f[l1,j]:=(f[l2,j-1]+f[l2,j]+f[l2,j+1]) mod 1000000007
else f[l1,j]:=f[l2,j-1]+f[l2,j]+f[l2,j+1];
end;
end
else
begin
j:=h[i];
if k=1 then f[l1,j]:=(f[l2,j-1]+f[l2,j]+f[l2,j+1]) mod 1000000007
else f[l1,j]:=f[l2,j-1]+f[l2,j]+f[l2,j+1];
end;
fillchar(f[l2],sizeof(f[l2]),0);
end;
writeln(f[l1,0] mod 1000000007);
close(input);
close(output);
end.