zoukankan      html  css  js  c++  java
  • 互不侵犯(BZOJ1087) 题解

    【题目描述】

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

    【样例输入】

        3 2

    【样例输出】

        16

    【解题思路】

        本题为SCOI2005的题,正解应该是状态压缩动态规划,把所有方案变为二进制存储,1为该位置摆放了国王,0为没有,因为一行最多九个格子,也就是说最多为511,空间上完全可以接受。然后我们可以先预处理一下所有可行的国王摆放的位置,以减少动规的次数,设f[i,j,k]为现在是第i行,用第j种方案,一共摆放了k个国王的总方案数,那么我们动规的条件就是f[i,j,k]=∑f[i-1,s,t]{s为与j不冲突的方案,t<=k}

        于是对于每个可行方案,我们需要记录一些东西:这个可行方案摆了多少国王,这个可行方案的攻击范围。那么满足条件的s即为s and j=0。

    【代码实现】

     1 type rec=record
     2      j,l,p:longint;
     3 end;
     4 var f:array[1..9,0..512,0..80] of int64;
     5     n,m,i,j,w,k,q,total,l:longint;
     6     ans:int64;
     7     fl:boolean;
     8     fa:array[1..500] of rec;
     9 procedure dfs(w,dep,t:longint);
    10 var i:longint;
    11     s:string;
    12     ch:string;
    13 begin
    14  if dep>n then
    15   begin
    16    inc(total);
    17    fa[total].j:=t;
    18    i:=t;
    19    s:='';
    20    while i<>0 do
    21     begin
    22      if i and 1=1 then
    23       inc(fa[total].l);
    24      str(i and 1,ch);
    25      s:=ch+s;
    26      i:=i shr 1;
    27     end;
    28    while length(s)<n do
    29     s:='0'+s;
    30    for i:=n downto 1 do
    31     if i=1 then
    32      begin
    33       if (s[i]='1')or(s[i+1]='1') then
    34        fa[total].p:=fa[total].p+(1 shl (n-i));
    35      end
    36     else
    37      if i=n then
    38       begin
    39        if (s[i]='1')or(s[i-1]='1') then
    40         fa[total].p:=fa[total].p+1;
    41       end
    42      else
    43       if (s[i]='1')or(s[i-1]='1')or(s[i+1]='1') then
    44        fa[total].p:=fa[total].p+(1 shl (n-i));
    45    exit;
    46   end;
    47  if w=1 then
    48   dfs(0,dep+1,t)
    49  else
    50   for i:=0 to 1 do
    51    begin
    52     t:=t+i shl (dep-1);
    53     dfs(i,dep+1,t);
    54    end;
    55 end;
    56 begin
    57  readln(n,m);
    58  if m>sqr((n+1)shr 1) then
    59   begin
    60    writeln(0);
    61    halt;
    62   end;
    63  dfs(0,1,0);
    64  for i:=1 to total do
    65   f[1,fa[i].j,fa[i].l]:=1;
    66  for i:=2 to n do
    67   for j:=1 to total do
    68    for l:=0 to ((n+1)shr 1)*(i-1) do
    69     if f[i-1,fa[j].j,l]=0 then
    70      continue
    71     else
    72      for k:=1 to total do
    73       if fa[j].p and fa[k].j=0 then
    74        inc(f[i,fa[k].j,l+fa[k].l],f[i-1,fa[j].j,l]);
    75  for i:=1 to total do
    76   ans:=ans+f[n,fa[i].j,m];
    77  writeln(ans);
    78 end.
  • 相关阅读:
    [ jquery 选择器 :hidden ] 此方法选取匹配所有不可见元素,或者type为hidden的元素
    剑指 Offer 03. 数组中重复的数字 哈希
    LeetCode 1736. 替换隐藏数字得到的最晚时间 贪心
    Leetcode 1552. 两球之间的磁力 二分
    Leetcode 88. 合并两个有序数组 双指针
    LeetCode 1744. 你能在你最喜欢的那天吃到你最喜欢的糖果吗?
    LeetCode 1743. 相邻元素对还原数组 哈希
    LeetCode 1745. 回文串分割 IV dp
    剑指 Offer 47. 礼物的最大价值 dp
    剑指 Offer 33. 二叉搜索树的后序遍历序列 树的遍历
  • 原文地址:https://www.cnblogs.com/PengBoLiuXu/p/4609441.html
Copyright © 2011-2022 走看看