现在的位置: 首页 > 综合 > 正文

bzoj1087

2018年01月15日 ⁄ 综合 ⁄ 共 3460字 ⁄ 字号 评论关闭

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.

【上篇】
【下篇】

抱歉!评论已关闭.