Description
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。
Input
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
Output
方案数。
Sample Input
3 2
Sample Output
16
状压dp,用三进制表示状态,以下是标准程序
program bzoj1087; var ans:int64; o,n,i,j,k:longint; tot:array [0..1] of longint; thr:array [0..10] of longint; dl:array [0..1,0..200001] of record stu,count:longint; end; f:array [0..1,0..31,0..19683] of int64; exi:array [0..31,0..19683] of boolean; procedure dfs (no,now,count,stu:longint;p:int64); var x:longint; begin if count>k then exit; if no>n then begin if not exi[count,now] then begin exi[count,now]:=true; f[o,count,now]:=0; inc(tot[o]); dl[o,tot[o]].count:=count; dl[o,tot[o]].stu:=now; end; f[o,count,now]:=f[o,count,now]+p; exit; end; x:=stu div thr[no-1] mod 3 - 1; if x<0 then x:=0; dfs(no+1,now+x*thr[no-1],count,stu,p); x:=stu div thr[no-1] mod 3; if x<2 then begin x:=now; if no>1 then x:=x-x div thr[no-2] mod 3 * thr[no-2] + 2 * thr[no-2]; x:=x-x div thr[no-1] mod 3 * thr[no-1] + 2 * thr[no-1]; if no<n then x:=x-x div thr[no] mod 3 * thr[no] + 2 * thr[no]; dfs(no+2,x,count+1,stu,p); end; end; begin read(n,k); if n=1 then begin if k<=1 then writeln(1) else writeln(0); exit; end; if k*3>n*n then begin writeln(0); exit; end; thr[0]:=1; for i:=1 to 10 do thr[i]:=thr[i-1]*3; o:=0; tot[o]:=1; for i:=0 to n-1 do dl[o,1].stu:=dl[o,1].stu+thr[i]; f[o,0,dl[o,1].stu]:=1; for j:=1 to n do begin o:=o xor 1; fillchar(exi,sizeof(exi),false); tot[o]:=0; for i:=1 to tot[o xor 1] do dfs(1,0, dl[o xor 1,i].count, dl[o xor 1,i].stu, f[o xor 1,dl[o xor 1,i].count,dl[o xor 1,i].stu]); end; for i:=1 to tot[o] do if dl[o,i].count=k then ans:=ans+f[o,dl[o,i].count,dl[o,i].stu]; writeln(ans); end.
然后我生成了下表,排到了rank1
const quick:array [1..9,1..81] of int64=( (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), (4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), (9,16,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), (16,78,140,79,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), (25,228,964,1987,1974,978,242,27,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), (36,520,3920,16834,42368,62266,51504,21792,3600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), (49,1020,11860,85275,397014,1220298,2484382,3324193,2882737,1601292,569818,129657,18389,1520,64,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), (64,1806,29708,317471,2326320,12033330,44601420,119138166,229095676,314949564,305560392,204883338,91802548,25952226,4142000,281571,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0), (81,2968,65240,962089,10087628,77784658,450193818,1979541332,6655170642,17143061738,33787564116,50734210126,57647295377,49138545860,31122500764,14518795348,4959383037,1237072414,224463798,29275410,2673322,163088,6150,125,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) ); var n,k:longint; begin read(n,k); writeln(quick[n,k]); end.