状压这个和二进制分不开关系

所以,对于二进制的熟悉是必不可少的技能

&  与操作,1不变,0变0

|  或操作,0不变,1变1  

^  异或操作,0不变,1取反   

~ 取反操作,把每一个二进制位0变1,1变0

还有一些复杂操作可以根据这些去理解

状态压缩

所谓状态压缩就是把dp的每一次转移时的状态用二进制来表示

或者用二进制来间接表示

比如

这里有10个苹果,编号1-10

我拿走了1,4,7,9这四个苹果

那么我们可以用011011010这一串二进制数来表示现在的状态

0表示这个位置没有苹果,1表示有

那么这就是一个状态

相比拿一个bool型的数组,这样表示更方便,内存更小,操作更简单

现在我想把拿走的苹果放回去,没拿走的拿走

那么状态就变成100100101

直接取反      a=011011010   b=100100101

a==~b;

这时候就充分展示了状态压缩的快捷性

下面我们讲一道例题。。。。。

在n*n(n≤20)的方格中放置n个车,每个车可以攻击所在的行和列,求方案总数

直接上排列组合,n!,很好理解啊

在n*n(n≤20)的方格棋盘上放置n 个车,某些格子不能放,求使它们不能互相攻击的方案总数。

这时候一些格子不能放,就要考虑每一行的情况

但是   ,,,,即使每一行中有的格子不能放,最终还是每一行每一列都要有一个车子

所以我们用s这个int型的数来表示现在的状态(行状态)

如果这一列现在有车子,那这一位就是1

所以最终s一定会变成11111111111(全是1)只有这样才能把n个车全部放进去

这样这一状态有几个车子说明这就是第几行

那这样转移方程就有了

dp[s]+=dp[s^(s&-s)];

for(;j>0;j-=(j&-j)){
dp[i]+=dp[i^(j&(-j))];
}

还有个问题,有些格子不能放车

这怎么办???????????

还记得前面的苹果吗

用1表示这里能放车子,0表示不可以

在状态转移的时候&一下就可以啦

j=i&s[num];

代码如下

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m;
long long dp[1<<20];
int s[25];
int main(){
memset(s,0x7fffffff,sizeof(s));
//if(s[1][1]==1)cout<<"sh";
//cout<<(s[1][1]&0)<<endl;
scanf("%d%d",&n,&m);
int x,y;
for(int i=1;i<=m;i++){
scanf("%d%d",&x,&y);
s[x]-=(1<<(y-1));
}
dp[0]=1;
for(int i=1;i<(1<<n);i++){
int j,num=0;
for(j=i;j>0;j-=(j&(-j))){
num++;
}
j=i&s[num];
for(;j>0;j-=(j&-j)){
dp[i]+=dp[i^(j&(-j))];
}
}
printf("%lld",dp[(1<<n)-1]);
}

这样基本的状压dp就结束了

也许你已经发现了

所有的n都小于等于20

因为int只有32位

这也是状压的前提

所以当你一直为空间时间复杂度着急时

就去考虑状压

而状压前先找到可以状压的数

就是32位以内的

over

状压dp(总结)状态压缩的更多相关文章

  1. 状压dp(状态压缩&&dp结合)学习笔记(持续更新)

    嗯,作为一只蒟蒻,今天再次学习了状压dp(学习借鉴的博客) 但是,依旧懵逼·································· 这篇学习笔记是我个人对于状压dp的理解,如果有什么不对的 ...

  2. [ An Ac a Day ^_^ ] POJ 3254 Corn Fields 状压dp

    题意: 有一块n*m的土地 0代表不肥沃不可以放牛 1代表肥沃可以放牛 且相邻的草地不能同时放牛 问最多有多少种放牛的方法并对1e8取模 思路: 典型的状压dp 能状态压缩 能状态转移 能状态压缩的题 ...

  3. 51Nod1626 B君的梦境 状压dp 矩阵

    原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1626.html 题目传送门 - 51Nod1626 题意 题解 首先考虑形象的想象本题中的思维空间. ...

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

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

  5. 有关状压DP

    [以下内容仅为本人在学习中的所感所想,本人水平有限目前尚处学习阶段,如有错误及不妥之处还请各位大佬指正,请谅解,谢谢!] 引言 动态规划虽然已经是对暴力算法的优化,但在某些比较特别的情况下,可以通过一 ...

  6. 【51Nod】1920 空间统计学 状压DP

    [题目]1920 空间统计学 [题意]给定m维空间中的n个点坐标,满足每一维坐标大小都在[0,3]之间,现在对于[0,3*m]的每个数字x统计曼哈顿距离为x的有序点对数.\(n \leq 2*10^5 ...

  7. 牛客练习赛49 B 筱玛爱阅读 (状压DP,子集生成)

    链接:https://ac.nowcoder.com/acm/contest/946/B 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262875K,其他语言5257 ...

  8. hdu4352-XHXJ's LIS状压DP+数位DP

    (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 题意:传送门  原题目描述在最下面.  在区间内把整数看成一个阿拉伯数字的集合,此集合中最长严格上升子序列的长度为k的个数. 思路: ...

  9. 状态压缩动态规划 状压DP

    总述 状态压缩动态规划,就是我们俗称的状压DP,是利用计算机二进制的性质来描述状态的一种DP方式 很多棋盘问题都运用到了状压,同时,状压也很经常和BFS及DP连用,例题里会给出介绍 有了状态,DP就比 ...

  10. dp乱写1:状态压缩dp(状压dp)炮兵阵地

    https://www.luogu.org/problem/show?pid=2704 题意: 炮兵在地图上的摆放位子只能在平地('P') 炮兵可以攻击上下左右各两格的格子: 而高原('H')上炮兵能 ...

随机推荐

  1. sublimeText常用插件

    扩展包: EmmetAlignmentDoc​BlockrSideBarEnhancementsFileDiffsColorsublimelocalizationAutoFileNameA File ...

  2. hdu3074 线段树求区间乘积(单点更新)

    题意:       给你n个数,两种操作,(1) 把第b个数改成c (2)算出b-c的乘积,结果对1000000007取余. 思路:       线段树单点更新,简单题目,不多解释,具体看代码. #i ...

  3. hdu4901 枚举状态(找集合对S(xor) ==T(and))

    题意:      给你一个串数字,然后让你在这里面挑取两个集合S ,T,集合的要求是 (1)不能为空 (2)S集合的所有元素必须在T集合的左边 (3)S集合的XOR == T集合的AND      问 ...

  4. AWVS扫描器的用法

    目录 AWVS AWVS功能介绍 AWVS如何工作 审核漏洞 AWVS11页面介绍 AWVS11中建立扫描 AWVS10.5中的介绍 AWVS11版本启动失败 利用Burpsuite修改AWVS的数据 ...

  5. C++基础:模板的声明实现分离

    模板的声明和实现为什么不能分离我不想废话了,我只是在想一种能够分离的方式. 文件 test.h 1 #pragma once 2 3 template<typename TC> 4 cla ...

  6. Day003 +和字符串使用的问题

    先看一段代码 int a=10; int b=20; System.out.println(""+a+b); System.out.println(a+b+"" ...

  7. Wampserver-添加虚拟主机

    鼠标左键点击,之后点击第一个 localhost(有一个小房子) 添加虚拟地址 具体添加 完成界面 注意:这个时候一定需要重启一个Wampserver64 如果没有重启直接进入4这个步骤,会发现进入的 ...

  8. Maven关于web.xml中Servlet和Servlet映射的问题

    在配置Servlet时,有两个地方需要配置. 一个是<servlet>,另一个是<servlet-Mapping>,这两个一个是配置Servlet,一个是配置其映射信息. &l ...

  9. Gridea博客无法载入CSS样式的解决办法

    今日在使用Gridea客户端更新博客的过程中,推送到远端仓库后内容显示正常,但是无法载入主题样式,就是没有载入CSS样式,折腾了一下午在搞懂问题出在哪里了,下面说一下自己的解决思路. 问题描述 首先, ...

  10. android之Parcelable

    java编程中,为了将对象的状态保存,需要将对象序列化. 在android中,序列化有两种方法可供选择,一个是java自带的序列化方法,只需实现Serializeable接口即可:另一个是androi ...