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.
  • 相关阅读:
    真正的e时代
    在线手册
    UVA 10616 Divisible Group Sums
    UVA 10721 Bar Codes
    UVA 10205 Stack 'em Up
    UVA 10247 Complete Tree Labeling
    UVA 10081 Tight Words
    UVA 11125 Arrange Some Marbles
    UVA 10128 Queue
    UVA 10912 Simple Minded Hashing
  • 原文地址:https://www.cnblogs.com/PengBoLiuXu/p/4609441.html
Copyright © 2011-2022 走看看