算是状压DP的经典题了

#\(\mathcal{\color{red}{Description}}\)

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

#\(\mathcal{\color{red}{Solution}}\)

嗯,然后今天(其实是前天)接触了一种新颖的\(DP\)——状压\(DP\)。其实就是一种借用二进制表示状态的方式,类似于“压缩”了一样。譬如说我需要马上得到一张01图上,某一行的状态,那我们就可以用二进制数来表示:$$100010_{(2)} = 34_{(10)}$$那么,对于这一行的状态,我们就可以用\(34\)这个数记录,而不是用数组来记录——瞬间减少了一维是不是?但其实还有更多的方便之处,比如说我们在\(DP\)的单次转移时,有时需要用到一整行的状态,用数组记录的话不便于转移,我们就需要用二进制来转移。

哦,还有,一般情况下状压之后都是倒着存的,因为这符合二进制的定义规则,比如我的一行的状态如此$$110101$$那么二进制下应该是$$101011$$可以类比一下,从左至右列标逐渐增大,但是二进制位从左到右权值逐渐减小。为了防止出现什么麻烦事儿,所以就倒着存了\(qwq\)。

嗯,那么它方便的地方在哪里呢?就是我们可以像访问数组的一行一样,甚至更快速的访问,比如:$$(1 << k - 1) & s$$可以询问状态\(s\)的第\(k\)位上是\(1\)是\(0\),$$(j >> k)<<k$$表示把状态\(j\)的二进制表示下最右边几位清零(你看数组就不能做直接清零)。

那对于这个题而言,1表示有我们用\(dp_{i,j,k}\)表示前\(i\)行,第\(i\)行状态是二进制表示(十进制下的值)为\(j\),放置了\(k\)个国王的方案数,那么状态转移方程就是$$dp_{i,j,k} = \sum dp_{i - 1, new, k - getlen(j)}$$

其中\(new\)表示我们所枚举的上一行的所有合法状态,\(getlen(j)\)表示\(j\)状态有多少位为\(1\),因为我们所定义的\(1\)即为放了国王。

其实好像对于一部分的东西是可以预处理出来的,但那时我偷了个懒,直接算的\(qwq\)

  1. #include <cstdio>
  2. #include <iostream>
  3. #define ll long long
  4. using namespace std ;
  5. ll dp[20][210][1026], ans ;
  6. int N, K, NN, i, j, k, l, L ;
  7. inline int _get(ll x){
  8. int ret = 0 ;
  9. while(x){
  10. if(x & 1) ret ++ ;
  11. x >>= 1 ;
  12. } return ret ;
  13. }
  14. inline bool check(ll x, ll y){
  15. if(x & y) return 1 ;
  16. if( (x << 1) & y) return 1 ;
  17. if( (x >> 1) & y) return 1 ;
  18. if( (y >> 1) & y) return 1 ;
  19. return 0 ;
  20. }
  21. int main(){
  22. cin >> N >> K ;
  23. dp[0][0][0] = 1, NN = (1 << N) - 1 ;
  24. for(i = 1; i <= N; i ++)
  25. for(j = 0; j <= K; j ++)
  26. for(k = 0; k <= NN; k ++){
  27. L = _get(k) ;
  28. if(L > j) continue ;
  29. if(k & (k >> 1)) continue ;
  30. for(l = 0; l <= NN; l ++){
  31. if(check(k ,l)) continue ;
  32. dp[i][j][k] += dp[i - 1][j - L][l] ;
  33. }
  34. }
  35. for(i = 0 ; i <= NN; i ++ ){
  36. ans += dp[N][K][i] ;
  37. }
  38. cout << ans ;
  39. }

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

  1. BZOJ1087[SCOI2005]互不侵犯——状压DP

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

  2. P1896 [SCOI2005]互不侵犯 状压dp

    正解:状压dp 解题报告: 看到是四川省选的时候我心里慌得一批TT然后看到难度之后放下心来觉得大概没有那么难 事实证明我还是too young too simple了QAQ难到爆炸TT我本来还想刚一道 ...

  3. SCOI2005 互不侵犯 [状压dp]

    题目传送门 题目大意:有n*n个格子,你需要放置k个国王使得它们无法互相攻击,每个国王的攻击范围为上下左走,左上右上左下右下,共8个格子,求最多的方法数 看到题目,是不是一下子就想到了玉米田那道题,如 ...

  4. [SCOI2005]互不侵犯 (状压$dp$)

    题目链接 Solution 状压 \(dp\) . \(f[i][j][k]\) 代表前 \(i\) 列中 , 已经安置 \(j\) 位国王,且最后一位状态为 \(k\) . 然后就可以很轻松的转移了 ...

  5. luogu1896 [SCOI2005]互不侵犯 状压DP

    题目大意 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子.( 1 <=N <=9, 0 ...

  6. NOI P1896 互不侵犯 状压DP

    题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 注:数据有加强(2018/4/25) ...

  7. _bzoj1087 [SCOI2005]互不侵犯King【dp】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1087 令f(i, j, k)表示前i列,二进制状态为j,已经用了k个国王的方案数,则 f(i ...

  8. 洛谷——P1896 [SCOI2005]互不侵犯

    P1896 [SCOI2005]互不侵犯 状压DP入门题 状压DP一般需要与处理状态是否合法,节省时间 设定状态dp[i][j][k]表示第i行第j个状态选择国王数为k的方案数 $dp[i][j][n ...

  9. 状压DP概念 及例题(洛谷 P1896 互不侵犯)

    状压DP 就是状态压缩DP.所谓状态压缩,就是将一些复杂的状态压缩起来,一般来说是压缩为一个二进制数,用01来表示某一元素的状态. 比如一排灯泡(5个) 我们可以用一串二进制01串来表示他们的状态 1 ...

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

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

随机推荐

  1. HDU 2084(DP)

    http://acm.hdu.edu.cn/showproblem.php?pid=2084 状态转移方程: dp[i][j] = MAX(dp[i+1][j],dp[i+1][j+1])+tower ...

  2. 拆系数FFT(任意模数FFT)

    拆系数FFT 对于任意模数 \(mod\) 设\(m=\sqrt {mod}\) 把多项式\(A(x)\)和\(B(x)\)的系数都拆成\(a\times m+b\)的形式,时\(a, b\)都小于\ ...

  3. 有标号的DAG计数系列问题

    传送门 II 设 \(f_i\) 表示 \(i\) 个点的答案 那么枚举至少 \(j\) 个点的出度为 \(0\) \[\sum_{j=0}^{i}(-1)^j\binom{i}{j}f_{i-j}2 ...

  4. 闲谈:乌云上那些 web-based 的 QQ 漏洞

    0×00 起始 昨日凌晨,看到爱尖刀团队发布了一条“腾讯客户端XSS,已第一时间提交至TSRC”的微博,心想,腾讯又出此类漏洞了.今日,由于有一位名叫“阿布”的同学将该漏洞发布到了乌云,引来不少争吵甚 ...

  5. kali 的端口扫描nmap

    输入“nmap+空格+“-O”+空格+IP地址或域名. 扫描所有TCP端口:输入“nmap+空格+“-sT”+空格+IP地址或域名” 扫描所有开放的UDP端口:输入“nmap+空格+”-sP”+空格+ ...

  6. 阿里,百度,腾讯招聘 Java 程序员的技术标准

    阿里巴巴篇 扎实的计算机专业基础,包括算法和数据结构,操作系统,计算机网络,计算机体系结构,数据库等 具有扎实的Java编程基础,理解IO.多线程等基础框架 熟练使用Linux系统的常用命令及shel ...

  7. 在centos6.x上安装teamviewer

    首先下载公钥: # wget http://www.teamviewer.com/link/?url=354858 # rpm --import TeamViewer_Linux_PubKey.asc ...

  8. dbcp2、c3p0、druid连接池的简单配置

    引入Maven依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="h ...

  9. 常规操作系统Windows系统淋雨系统Unix系统netware等系统介绍分析

    服务器操作系统有有很多,比如说:Windows.Linux.Unix和Netware......但我们经常用过仅有Windows和Linux.下面简单为大家介绍一下常见服务器操作系统. 1.Windo ...

  10. 最近选购MP3而有感便携追求音质的一些心得

    之前的创新小石头MP3的耳机接口松动了.考虑到它已经服役了4年了.所以我准备重新买一个.而小石头出色的外放,我决定让给宝宝当玩具. 选购心得MP3的时候,原来的主导思想,是在低价位的里面考虑一台国际品 ...