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.
  • 相关阅读:
    关于Spring和Struts2的整合
    有关Transaction not successfully started问题解决办法
    两种页面跳转
    jdbc连接mysql
    change和modify
    Navicat Premium 15连接Oracle时提示oracle library is not loaded的解决方案
    Oracle创建本地数据库实例及配置监听
    下载Visual Studio 2019离线安装包
    简单的数据库
    未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序
  • 原文地址:https://www.cnblogs.com/PengBoLiuXu/p/4609441.html
Copyright © 2011-2022 走看看