状压DP概念 及例题(洛谷 P1896 互不侵犯)
状压DP 就是状态压缩DP。所谓状态压缩,就是将一些复杂的状态压缩起来,一般来说是压缩为一个二进制数,用01来表示某一元素的状态。
比如一排灯泡(5个) 我们可以用一串二进制01串来表示他们的状态 11111就是全开 00000就是全关 00001就是只开了第五个 00101就是第三和第五个开了 以此类推.....而这个二进制串是可以用一个十进制数表示的 比如31就是11111 ,1就是00001等等,这样我们在遍历的时候就不用将五个灯泡疯狂循环,只需要从0遍历到31即可 大大节省了时空。
这里需要解释的是,空间的节省是很显然的,本来需要开一个a[5]的数组来存这些灯泡的一种状态,现在只需要一个数了,但是时间复杂度是怎么体现的呢?明明都是2^5种情况呀!似乎并没有节省遍历带来的时间复杂度......这是因为对于二进制的操作要比通过对存储的状态进行模拟简单得多 举个例子来说:假如我们要求这些灯泡相邻的不能同时亮,如果没有用到状压,就是对每种状态进行判断,如果相邻的状态一样就跳出,那么每种状态都需要从1到5扫一遍,这是很麻烦的,但是经过状压之后,这就容易许多了:x&(x<<1) 即可,比之前的方式省时省力!
需要强调的是,状压本身对于dp没有影响,该怎么dp还是怎么dp,但是对于遍历和操作却方便了很多。
下面列出一些二进制的常规操作(江苏省淮阴中学薛志坚整理)
还有求当前二进制串中1的数量 这个是我写这个博客的时候看到的
int sum=;
while(x){
++sum;
x&=x-;
}
例题
我们采用dp[i][j][s]来表示第i行的状态是j的情况下 前i行放了s个国王的方法总数 很明显,dp[i][j][s]+=dp[i-1][k][s-sum(j)] 其中k代表上一行的状态,sum(j)代表第i行的国王数。
具体来看代码:
#include<bits/stdc++.h> using namespace std; long long int sit,i,N,K,j,k,s,n,dp[][<<][],a[<<],anss; long long int sum(long long int i) //求状态i的国王数
{
long long int a=;
while(i)
{
if(i&)
a++;
i=i>>;
}
return a;
} int main()
{
cin>>N>>K;
n=<<N;
for(i=;i<n;i++)
{
if(i&(i<<)) //判断左右国王是否冲突
continue;
a[++sit]=i;
dp[][sit][sum(i)]=; //初始化
}
for(i=;i<=N;i++)
{
for(k=;k<=sit;k++) //上一行
{
for(j=;j<=sit;j++) //本行
{
if(a[k]&a[j]) //上下有国王冲突
continue;
if(a[k]&(a[j]<<)) //右上有国王冲突
continue;
if(a[k]&(a[j]>>)) //左上有国王冲突
continue;
for(s=K;s>=sum(a[j])+sum(a[k]);s--) //遍历前i行放置的国王总数 这里我看的其他博客上写的都是 s>=sum(a[j]) 但是我感觉不需要 因为你得满足前一行的状态
dp[i][j][s]+=dp[i-][k][s-sum(a[j])];
}
}
}
for(i=;i<=sit;i++)
anss+=dp[N][i][K]; //遍历最后一行的状态 输出答案
cout<<anss<<endl;
}
需要注意的是 要用 long long 否则是70分......
状压DP概念 及例题(洛谷 P1896 互不侵犯)的更多相关文章
- 状压dp大总结1 [洛谷]
前言 状态压缩是一种\(dp\)里的暴力,但是非常优秀,状态的转移,方程的转移和定义都是状压\(dp\)的难点,本人在次总结状压dp的几个题型和例题,便于自己以后理解分析状态和定义方式 状态压缩动态规 ...
- 洛谷P1896 互不侵犯
又是一道状压DP求方案数的题... 多了一个放k个的限制,于是我们把数组多开一维. f[i][j][k]表示前i行放了j个,第i行状态为k的方案数. 然后老套路DFS转移,这次要多记录一个cnt表示上 ...
- 洛谷 P1896 互不侵犯King
P1896 [SCOI2005]互不侵犯King 题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共 ...
- 状压dp之二之三 炮兵阵地/玉米田 By cellur925
一.简单的状压dp 玉米田 题目描述 Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ ...
- 状压dp入门
状压dp的含义 在我们解决动态规划题目的时候,dp数组最重要的一维就是保存状态信息,但是有些题目它的具有dp的特性,并且状态较多,如果直接保存的可能需要三维甚至多维数组,这样在题目允许的内存下势必是开 ...
- 洛谷P3959 宝藏(NOIP2017)(状压DP,子集DP)
洛谷题目传送门 Dalao的题解多数是什么模拟退火.DFS剪枝.\(O(3^nn^2)\)的状压DP之类.蒟蒻尝试着把状压改进了一下使复杂度降到\(O(3^nn)\). 考虑到每条边的贡献跟它所在的层 ...
- 【题解】洛谷P3959 [NOIP2017TG] 宝藏(状压DP+DFS)
洛谷P3959:https://www.luogu.org/problemnew/show/P3959 前言 NOIP2017时还很弱(现在也很弱 看出来是DP 但是并不会状压DP 现在看来思路并不复 ...
- 【题解】洛谷P2704 [NOI2001] 炮兵阵地(状压DP)
洛谷P2704:https://www.luogu.org/problemnew/show/P2704 思路 这道题一开始以为是什么基于状压的高端算法 没想到只是一道加了一行状态判断的状压DP而已 与 ...
- 【题解】洛谷P1896 [SCOI2005] 互不侵犯(状压DP)
洛谷P1896:https://www.luogu.org/problemnew/show/P1896 前言 这是一道状压DP的经典题 原来已经做过了 但是快要NOIP 复习一波 关于一些位运算的知识 ...
随机推荐
- C语言字符型数据的ASCII码值为何是负数?
有如下一段C语言程序: #include "stdio.h" int main(void) { char a = 0xC8; printf ("字符a的ASCII码值的1 ...
- Java编程思想:进程控制
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public ...
- 推荐 2 款超牛逼、炫酷、实用的Docker管理工具!
Docker技术的火热程度,想必每个互联网IT技术人员都能时时感受的到,的确,近些年,国内对于Docker容器技术的应用需求越来越强烈!! 人均年薪80万以上,docker到底是什么?为什么这么火? ...
- u盘制作启动盘步骤以及安装win10步骤
1.下载制作工具:微PE工具箱V2.0 http://www.wepe.com.cn/download.html 2.默认制作启动盘 3.下载win10镜像 ed2k://|file|cn_windo ...
- java练习---12
public class L1106 { public static void main(String[] args) { // TODO Auto-generated method stub Tes ...
- RobotFramework_2.新建项目、新建用例、运行用例和查看测试报告
RobotFramework的使用 新建一个项目 Robotframework-ride的界面 分了四个区域:菜单栏.工具栏.案例及资源区.工作区,如下图: 创建项目 首先,点击File-New Pr ...
- mybatis01-1测试
首先需要数据源信息和日志文件 然后一个SQLMapConfig.xml配置文件连接数据库并且映射后一个xml文件,另一个xml文件写入SQL语句, 最后text测试文件读取第一个配置文件,放到SQLS ...
- 实现万行级excel导出---poi--ooxm的应用和采坑
xl_echo编辑整理,欢迎转载,转载请声明文章来源.欢迎添加echo微信(微信号:t2421499075)交流学习. 百战不败,依不自称常胜,百败不颓,依能奋力前行.--这才是真正的堪称强大!! - ...
- [开源] .NETCore websocket 即时通讯组件---ImCore
前言 ImCore 是一款 .NETCore 下利用 WebSocket 实现的简易.高性能.集群即时通讯组件,支持点对点通讯.群聊通讯.上线下线事件消息等众多实用性功能. 开源地址:https:// ...
- springBoot数据校验与统一异常处理
概念 异常,在程序中经常发生,如果发生异常怎样给用户一个良好的反馈体验就是我们需要处理的问题.以前处理异常信息,经常都是给前端一个统一的响应,如数据错误,程序崩溃等等.没办法指出哪里出错了,这是一种对 ...