题意:求将k个象摆在
一开始想用类似8皇后的位运算来做,但皇后每行只能放一个,象每行可以放多个,同样的方法枚举复杂度就会高很多。复杂度无法估计,每层转移2n但不满,反正这种复杂度只过了70%的点。
var
n,k,limit:longint;
ans:int64;
function count(x:longint):longint;
begin
count:=0;
while x>0 do
begin
inc(count,x and 1);
x:=x>>1;
end;
end;
procedure dfs(dep,left,right,sum:longint);
var
can,now:longint;
begin
if (dep>n) then
begin
inc(ans,ord(sum=k));
exit;
end;
can:=(limit xor (left or right));
now:=can;
while now>0 do
begin
if sum+count(now)<=k
then dfs(dep+1,((left or now)<<1) and limit,(right or now)>>1,sum+count(now));
now:=(now - 1) and can;
end;
if sum+count(now)<=k
then dfs(dep+1,(left<<1) and limit,right>>1,sum+count(now));
end;
begin
assign(input,'elephant.in');reset(input);
assign(output,'elephant.out');rewrite(output);
read(n,k);
limit:=1<<n-1;
dfs(1,0,0,0);
writeln(ans);
close(input);close(output);
end.
实际上如果把棋盘斜过来,黑白染色,分成两块棋盘,每块棋盘上的象其实就相当于車了,而且上下行可以互换,那样把两个棋盘的行都按照从小到大排列,那么一个棋盘的每行格子数就是1 1 3 3 5 5......另一个棋盘每行格子数为2 2 4 4……,这样就可以n2dp,用f[i][j]表示前i行取了
const
MAXN=8;
var
f,g:array[0..MAXN*2,0..MAXN*2] of int64;
a,b:array[0..MAXN*2] of int64;
n,k,i,j:longint;
ans:int64;
procedure print(x:int64);
begin
writeln(x);
close(input);close(output);
halt;
end;
function max(a,b:longint):longint;
begin if (a>b) then exit(a) else exit(b); end;
function min(a,b:longint):longint;
begin if (a<b) then exit(a) else exit(b); end;
begin
assign(input,'elephant.in');reset(input);
assign(output,'elephant.out');rewrite(output);
read(n,k);
if (n=1) then print(1);
if (k>(n-1)<<1) then print(0);
for i:=1 to n do
if (i and 1=1)
then a[i]:=i
else a[i]:=a[i-1];
for i:=1 to n-1 do
if (i and 1=1)
then b[i]:=i+1
else b[i]:=b[i-1];
f[0][0]:=1;
for i:=0 to n-1 do
for j:=0 to a[i] do
begin
inc(f[i+1][j],f[i][j]);
inc(f[i+1][j+1],f[i][j] * (a[i+1] - j));
end;
g[0][0]:=1;
for i:=0 to n-2 do
for j:=0 to b[i] do
begin
inc(g[i+1][j],g[i][j]);
inc(g[i+1][j+1],g[i][j] * (b[i+1] - j));
end;
for i:=max(0,k-b[n-1]) to min(a[n],k) do
inc(ans,f[n][i] * g[n-1][k-i]);
print(ans);
close(input);close(output);
end.