• [BZOJ1087][SCOI2005]互不侵犯King解题报告|状压DP


    在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。

      好像若干月前非常Naive地去写过DFS...

      然后其实作为状压DP是一道非常好的题啦><

      感觉直接无脑搞时间是下不来的 做了好几道预处理

      使得最后DP的过程中没有任何一条转移是无用的

      

     1 program bzoj1087;
     2 var i,x,n,k,j,p,q,t1,t2:longint;
     3     ans:int64;
     4     a:array[-1..512]of longint;
     5     b:array[-1..9,-1..100]of longint;
     6     c:array[-1..512,-1..512]of longint;
     7     f:array[0..1,-1..512,-1..512]of int64;
     8 
     9 function check(x:longint):boolean;
    10 var las:longint;
    11 begin
    12     las:=0;
    13     while x<>0 do
    14     begin
    15         if (x and 1=1)and(las=1) then exit(false);
    16         las:=x and 1;
    17         x:=x >> 1;
    18     end;
    19     exit(true);
    20 end;
    21 
    22 function count(x:longint):longint;
    23 var tem:longint;
    24 begin
    25     tem:=0;
    26     while x<>0 do
    27     begin
    28         inc(tem,x and 1);
    29         x:=x >> 1;
    30     end;
    31     exit(tem);
    32 end;
    33 
    34 function ok(x,y:longint):boolean;
    35 var i:longint;
    36     tmp:array[0..1,-1..10]of longint;
    37 begin
    38     for i:=8 downto 0 do tmp[0,i]:=x >> i and 1;
    39     for i:=8 downto 0 do tmp[1,i]:=y >> i and 1;
    40     for i:=0 to 8 do if (tmp[0,i]+tmp[1,i]=2)or(tmp[0,i]+tmp[1,i-1]=2)or(tmp[0,i]+tmp[1,i+1]=2) then exit(false);
    41     exit(true);
    42 end;
    43 
    44 begin
    45     fillchar(b,sizeof(b),0);
    46     fillchar(a,sizeof(a),0);
    47     fillchar(c,sizeof(c),0);
    48         readln(n,k);
    49         for i:=0 to 1 << n-1 do if check(i) then
    50     begin
    51             x:=count(i);
    52         inc(b[x,0]);b[x,b[x,0]]:=i;
    53         inc(a[0]);a[a[0]]:=i;
    54     end;
    55     for i:=1 to a[0] do
    56         for j:=1 to a[0] do if ok(a[i],a[j]) then begin inc(c[a[i],0]);c[a[i],c[a[i],0]]:=a[j];end;
    57     fillchar(f,sizeof(f),0);
    58     for i:=0 to k do
    59         for j:=1 to b[i,0] do f[1,i,b[i,j]]:=1;
    60     for i:=2 to n do
    61     begin
    62         f[0]:=f[1];
    63         fillchar(f[1],sizeof(f[1]),0);
    64         for j:=0 to k do
    65             for p:=0 to (n+1) >> 1 do if p<=j then
    66             begin
    67                 q:=j-p;
    68                 for t1:=1 to b[p,0] do
    69                     for t2:=1 to c[b[p,t1],0] do inc(f[1,j,b[p,t1]],f[0,q,c[b[p,t1],t2]]);
    70             end;
    71     end;
    72     ans:=0;
    73     for i:=1 to a[0] do inc(ans,f[1,k,a[i]]);
    74     writeln(ans);
    75 end.
  • 相关阅读:
    【Python】自己写日志功能
    shell 笔记
    python 字典,字典嵌套,字典遍历
    python基础 循环,列表,切片,列表增删改查
    Dva_react使用问题总结
    ts_react_test报错解决方法
    如何写好项目规划和方案设计文档 (转)
    script标签引入react环境三个必须cdn文件
    react点击事件对象( react封装过后事件对象 )
    react简书笔记一 环境, git 和 项目 关联
  • 原文地址:https://www.cnblogs.com/mjy0724/p/4480049.html
Copyright © 2020-2023  润新知