SDOI 2010 and SXOI 2014 地精部落 (递推)

时间:2021-08-29 06:07:20

用E[i,j]表示共有i个数字,以1..j开头且一开始下降的方案数的总和。则我们有:

E[i,j]:=E[I,J-1]+E[i-1,i-j]

我们先来证明上升与下降的方案是一一对应的。

事实上,若有a1,a2,a3,……,an 为满足要求的一个序列(上升或下降),

则我们构造新数列,n+1-a1,n+1-a2,n+1-a3,……,n+1-an 这个数列也满足要求(下降或上升)。

而且这种对应是一一对应的,其正确性是显然的。

令f[i,j]表示共i个数字,以j开头的下降的方案数

令g[i,j]表示共i个数字,以j开头的上升的方案数

则我们有f[i,j]:=g[i,i+1-j](因为它们是一一对应的)。

所以f[i,j]=g[i-1,j-1]+g[i-1,j-2]+……+g[i-1,1]

=f[i-1,i-j+1]+f[i-1,i-j+2]+……+f[i-1,i-1]

=E[i-1,i-1]-E[i-1,i-j]

于是E[i,j]:=E[i,j-1]+f[i,j]=E[i,j-1]+E[i-1,i-1]-E[i-1,i-j];

var i,j,n,p,x:longint;
f:array[..,..] of longint;
begin
readln(n,p);
f[,]:=;x:=;
for i:= to n do
begin
x:=-x;
for j:= to i do
begin
f[x,j]:=f[x,j-]+f[-x,i-j];
if f[x,j]>=p then dec(f[x,j],p);
end;
end;
if n= then writeln()
else writeln(f[n mod ,n]* mod p);
end.

待修改……