[SCOI2005]互不侵犯King

【题目描述】

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

【输入】

只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)

【输出】

方案数。

【样例输入】

3 2

【样例输出】

16

分析:

经典的状压DP题目,可我竟然调了很长时间都没对,后来发现是DP枚举范围错了,直接枚举到最大情况导致答案大得离谱,所以透彻理解算法很重要。

其它懒得写了。

代码1(第一次写的代码很丑,还很多余地在每个二进制首位增添一个1......):

  1. program king;
  2. var
  3. f:array[..,..,..]of int64;
  4. a:array[..,..]of ..;
  5. sum1,w:array[..]of longint;
  6. g:array[..,..]of boolean;
  7. h:array[..]of boolean;
  8. n,i,m,j,k,u,v,l,num,num1:longint;
  9. procedure work(x:longint);
  10. var i,c,y:longint;
  11. begin
  12. i:=x; c:=;
  13. while i> do
  14. begin
  15. a[x,c]:=i mod ; if a[x,c]= then begin inc(sum1[x]); if c> then y:=-c+; end;
  16. i:=i div ;
  17. c:=c-;
  18. end;
  19. dec(sum1[x]); w[x]:=y;
  20. end;
  21. begin
  22. readln(n,k);num1:=;num:=;
  23. for i:= to n do num:=num*;
  24. num:=num1+num-;
  25. for i:=num1 to num do
  26. begin
  27. work(i);
  28. end;
  29. for u:=num1 to num do
  30. for v:=num1 to num do
  31. for l:= to do begin g[u,v]:=true;
  32. if (a[u,l]=)and(((a[v,l-]=)and(l>))or(a[v,l]=)or(a[v,l+]=)) then begin g[u,v]:=false;break; end;
  33. if (a[v,l]=)and(((a[u,l-]=)and(l>))or(a[u,l]=)or(a[u,l+]=)) then begin g[u,v]:=false;break; end;
  34. end;
  35. fillchar(f,sizeof(f),);
  36. for i:=num1 to num do begin h[i]:=true;
  37. for j:= to do
  38. if ((a[i,j]=)and(((a[i,j-]=)and(j>))or(a[i,j+]=))) then begin h[i]:=false; break; end;
  39. if h[i]=true then f[,i,sum1[i]]:=;
  40. end;
  41. for i:= to n+ do
  42. for j:= to k do
  43. for u:=num1 to num do
  44. if (sum1[u]<=j)and(h[u]=true) then
  45. for v:=num1 to num do
  46. if (sum1[v]+sum1[u]<=j)and(h[v]=true) then
  47. begin
  48. if g[u,v]=true then f[i,u,j]:=f[i,u,j]+f[i-,v,j-sum1[u]];
  49. end;
  50. writeln(f[n+,num1,k]);
  51. end.

代码2(改进的代码,用了一些位运算,比第一次好看一点):

  1. program king;
  2. var
  3. f:array[..,..,..]of int64;
  4. sum1:array[..]of longint;
  5. g:array[..,..]of boolean;
  6. h:array[..]of boolean;
  7. n,i,m,j,k,u,v,l,t,num:longint;
  8. begin
  9. readln(n,k);
  10. fillchar(g,sizeof(g),false);
  11. fillchar(h,sizeof(h),false);
  12. fillchar(f,sizeof(f),);
  13. num:=;
  14. for i:= to n do num:=num*; num:=num-;
  15. for i:= to num do
  16. if i and (i shr )= then
  17. begin
  18. j:=i;t:=;
  19. while j> do begin t:=t+j and ; j:=j shr ; end;
  20. sum1[i]:=t; h[i]:=true;
  21. end;
  22. for i:= to num do if h[i]=true then
  23. for j:= to num do if h[j]=true then
  24. if (i and j=)and(i and (j shr )=)and(j and (i shr )=) then g[i,j]:=true;
  25. for i:= to num do if h[i]=true then f[,i,sum1[i]]:=;
  26. for i:= to n+ do
  27. for j:= to k do
  28. for u:= to num do if (h[u]=true)and(sum1[u]<=j) then
  29. for v:= to num do if (h[v]=true)and(sum1[u]+sum1[v]<=j) then
  30. if g[v,u]=true then
  31. inc(f[i,u,j],f[i-,v,j-sum1[u]]);
  32. writeln(f[n+,,k]);
  33. end.

BZOJ 1087:[SCOI2005]互不侵犯King(状压DP)的更多相关文章

  1. BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3336  Solved: 1936[Submit][ ...

  2. BZOJ 1087 [SCOI2005]互不侵犯King ——状压DP

    [题目分析] 沉迷水题,吃枣药丸. [代码] #include <cstdio> #include <cstring> #include <iostream> #i ...

  3. bzoj 1087 [SCOI2005]互不侵犯King 状态压缩dp

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MB[Submit][Status][Discuss] Descripti ...

  4. 【BZOJ1087】 [SCOI2005]互不侵犯King 状压DP

    经典状压DP. f[i][j][k]=sum(f[i-1][j-cnt[k]][k]); cnt[i]放置情况为i时的国王数量 前I行放置情况为k时国王数量为J #include <iostre ...

  5. [BZOJ1087] [SCOI2005] 互不侵犯King (状压dp)

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

  6. 互不侵犯king (状压dp)

    互不侵犯king (状压dp) 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子.\(1\le n\ ...

  7. BZOJ-1087 互不侵犯King 状压DP+DFS预处理

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2337 Solved: 1366 [Submit][ ...

  8. bzoj1087 互不侵犯King 状压dp+bitset

    题目传送门 题目大意:中文题面. 思路:又是格子,n又只有9,所以肯定是状压dp,很明显上面一行的摆放位置会影响下一行,所以先预处理出怎样的二进制摆放法可以放在上下相邻的两行,这里推荐使用bitset ...

  9. BZOJ 1087 [SCOI2005]互不侵犯King(状压DP)

    题意:在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子.n<=9 思路:状压dp,dp[i][ ...

  10. [SCOI2005]互不侵犯(状压DP)

    嗝~算是状压DP的经典题了~ #\(\mathcal{\color{red}{Description}}\) 在\(N×N\)的棋盘里面放\(K\)个国王,使他们互不攻击,共有多少种摆放方案.国王能攻 ...

随机推荐

  1. py2exe --- show error: MSVCP90.dll + matplotlib issues

    问题1: show error: MSVCP90.dll: No such file or directory 创建生成exe文件的脚本添加: import py2exe from distutils ...

  2. 2018.6.19 Java核心API与高级编程实践复习总结

    Java 核心编程API与高级编程实践 第一章 异常 1.1 异常概述 在程序运行中,经常会出现一些意外情况,这些意外会导致程序出错或者崩溃而影响程序的正常执行,在java语言中,将这些程序意外称为异 ...

  3. python剑指offer 链表中环的入口节点

    题目: 一个链表中包含环,请找出该链表的环的入口结点. 思路: 先说个定理:两个指针一个fast.一个slow同时从一个链表的头部出发, fast一次走2步,slow一次走一步,如果该链表有环,两个指 ...

  4. 【转】mongoDB 学习笔记纯干货(mongoose、增删改查、聚合、索引、连接、备份与恢复、监控等等)

    mongoDB 学习笔记纯干货(mongoose.增删改查.聚合.索引.连接.备份与恢复.监控等等) http://www.cnblogs.com/bxm0927/p/7159556.html

  5. Drupal7强制把主题恢复到默认主题

    今天在写Theme,退出登陆的时候无法进入管理后台. 万不得已之下只有使用数据库进行恢复. Rest Drupal Theme to Bartik SQL语句如下: WHERE type = 'the ...

  6. k8s的认证和service account简述

    k8s的认证: 与API server通信的客户端大致有两类:  1.集群客户端工具(kubectl.kubeadm.kubelet等)  2.集群内pod. 任何客户端访问k8s时的过程:  1.认 ...

  7. Python_循环判断表达式

    一.if判断 计算机之所以能做很多自动化的任务,因为它可以自己做条件判断. if判断结构: if 条件: 动作 elif 条件: 动作 else: 动作 if判断年龄: age_of_princal ...

  8. 在windows和Linux下安装nodejs

    在windows下安装nodejs 1.首先下载nodejs安装包,  https://nodejs.org/en/download/ 点击下载相应的版本 然后将文件夹解压到安装目录(任意,不做规定) ...

  9. linux 服务器被植入ddgs、qW3xT.2挖矿病毒处理记录

    被入侵后的现象: 发现有qW3xT.2与ddgs两个异常进程,消耗了较高的cpu,kill掉后 过一会就会重新出现. kill 掉这两个异常进程后,过一段时间看到了如下进程: 首先在/etc/sysc ...

  10. Gym - 101128F Landscaping(网络流)

    题意 给你一个\(N×M\)的草地,有高地有低地. 收割机从低地走到高地或者从高地走到低地都要花费用\(A\),你可以花费用\(B\)把一块高地变成低地,或者把一块低地变成高地.收割机每行每列都是必须 ...