状态压缩动态规划(状压DP)详解
0 引子
不要999,也不要888,只要288,只要288,状压DP带回家。你买不了上当,买不了欺骗。它可以当搜索,也可以卡常数,还可以装B,方式多样,随心搭配,自由多变,一定符合你的口味!
在计算机里,整数是以二进制的方式存储的。把状态信息压缩成二进制当成状态进行动态规划,就是状压DP的基本思想。
是不是一脸懵比?别急着关掉文章,接着往下看,你会发现一个新世界。
0.5 状压能解决什么样的问题?
让我们康康这道题:传送门
很容易想到搜索,不是吗?
然而,我们要用更装比 复杂 优美的方式完成这道题。
1.什么是“状态压缩?”
举个例子吧。例如,例题里的“取哪些砝码”这个信息,就可以压缩进一个int整数里。因为,int整数是二进制存储的。大概长这样:
| 十进制 | 二进制(也就是计算机里实际的状态) |
|---|---|
| 1 | 1 |
| 2 | 10 |
| 114514 | 11011111101010010 |
| 6 | 110 |
我们可以发现,数字是由许多二进制位构成的,要么是0要么是1。
是不是发现了什么?
没错,我们可以用每一位的0和1表示每一个砝码选或者不选!
例如,数字 2 (二进制:10) 就可以表示1号砝码不选,2号砝码选的状态。(因为第1位是0,第2位是1)。
知道了如何压缩,就可以用动态规划的方式求解了。
2.如何枚举出每一个状态?
事实上十分简单,这样就可以:
for(int i=0;i<=(1<<n)-1;i++){
}
(1<<n是把1左移n位的意思。例如,1<<3的二进制就是1000,十进制就是8)
我们来模拟一下\(n=3\)时的情况。
| i | i的二进制 |
|---|---|
| 0 | 000 |
| 1 | 001 |
| 2 | 010 |
| 3 | 011 |
| 4 | 100 |
| 5 | 101 |
| 6 | 110 |
| 7 | 111 |
可以发现,i把所有砝码选取情况都枚举出来了。
3.如何转移?
这个其实因题而异,我就用这道题举例子吧
for(int i=1;i<(1<<n);i++){//枚举。因为i=0就是一个也不选,所以不需要枚举。
int high_bit=0,high_bit_num=0;
for(int j=31;j>=0;j--){//int最多有31位,所以j=31-0。
if((i>>j)&1){//意思是i的第j位是否为1
high_bit=1<<j;
high_bit_num=j;
break;//找到了就退出来
}
}//求出当前方案的最高位
sum[i]=sum[i^high_bit]+a[high_bit_num+1];//转移。因为i是“按顺序”枚举的,所以去掉最高位后的方案一定枚举过了。
//i^high_bit的意思是去掉最高位
cnt[i]=cnt[i^high_bit]+1;
}
(这段代码求的是每种砝码选取方案的重量和与每种砝码选取方案要用多少砝码)
注释写的很详细,我就不再罗嗦了。
4.如果你想A掉这道题
你可以康康我的题解:传送门
但是我还是建议你自己做出来
5.写在最后
状压dp和其它所有算法一样,需要大量的练习才能掌握。
这篇文章写的可能不怎么全面,欢迎在评论区提问或指出。另外,不要吊死在一棵树上,多康康别人的文章吧。
状态压缩动态规划(状压DP)详解的更多相关文章
- 状态压缩动态规划 状压DP
总述 状态压缩动态规划,就是我们俗称的状压DP,是利用计算机二进制的性质来描述状态的一种DP方式 很多棋盘问题都运用到了状压,同时,状压也很经常和BFS及DP连用,例题里会给出介绍 有了状态,DP就比 ...
- 状态压缩dp 状压dp 详解
说到状压dp,一般和二进制少不了关系(还常和博弈论结合起来考,这个坑我挖了还没填qwq),二进制是个好东西啊,所以二进制的各种运算是前置知识,不了解的话走下面链接进百度百科 https://baike ...
- 状压DP详解+题目
介绍 状压dp其实就是将状态压缩成2进制来保存 其特征就是看起来有点像搜索,每个格子的状态只有1或0 ,是另一类非常典型的动态规划 举个例子:有一个大小为n*n的农田,我们可以在任意处种田,现在来描述 ...
- 状压DP详解(位运算)
前言: 状压DP是一种非常暴力的做法(有一些可以排除某些状态的除外),例如dp[S][v]中,S可以代表已经访问过的顶点的集合,v可以代表当前所在的顶点为v.S代表的就是一种状态(二进制表示),比如 ...
- hihoCoder 1044 : 状态压缩·一 状压dp
思路:状态压缩,dp(i, j)表示考虑前i个数且[i-m+1, i]的选择情况为j.如果要选择当前这个数并且,数位1的个数不超过q,则dp[i+1][nex] = max(dp[i+1][nex], ...
- hihocoder #1044 : 状态压缩·一 状压DP
http://hihocoder.com/problemset/problem/1044 可以看出来每一位的选取只与前m位有关,我们把每个位置起始的前m位选取状态看出01序列,就可以作为一个数字来存储 ...
- 动态规划---状压dp
状压dp,就是把动态规划之中的一个个状态用二进制表示,主要运用位运算. 这里有一道例题:蓝书P639猛兽军团1 [SCOI2005]互不侵犯 题目: 题目描述 在N×N的棋盘里面放K个国王,使他们互不 ...
- 【bzoj3195】【 [Jxoi2012]奇怪的道路】另类压缩的状压dp好题
(上不了p站我要死了) 啊啊,其实想清楚了还是挺简单的. Description 小宇从历史书上了解到一个古老的文明.这个文明在各个方面高度发达,交通方面也不例外.考古学家已经知道,这个文明在全盛时期 ...
- 【状压DP】bzoj1087 互不侵犯king
一.题目 Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上.下.左.右,以及左上.左下.右上.右下八个方向上附近的各一个格子,共8个格子. I ...
随机推荐
- 6.29 省选模拟赛 坏题 AC自动机 dp 图论
考场上随手构造了一组数据把自己卡掉了 然后一直都是掉线状态了. 最后发现这个东西不是subtask -1的情况不多 所以就没管无解直接莽 写题有点晚 故没调出来.. 考虑怎么做 容易想到建立AC自动机 ...
- luogu P6224 [BJWC2014]数据 KD-tree 标准板子 重构+二维平面内最近最远距离查询
LINK:数据 这是一个我写过的最标准的板子. 重构什么的写的非常的标准 常数应该也算很小的. 不过虽然过了题 我也不知道代码是否真的无误 反正我已经眼查三遍了... 重构:建议先插入 插入过程中找到 ...
- 性能分析(3)- 短时进程导致用户 CPU 使用率过高案例
性能分析小案例系列,可以通过下面链接查看哦 https://www.cnblogs.com/poloyy/category/1814570.html 系统架构背景 VM1:用作 Web 服务器,来模拟 ...
- Sharding-JDBC主键生成策略
当使用分库分表等功能之后,就不能再依赖数据库自带的主键生成机制了,一方面主键ID不能重复,另外需要在新增之前就知道主键ID,才能保证ID能够均匀分布到不同的数据库或数据表中,所以要使用一个合理的主键生 ...
- IdentityServer4 (3) 授权码模式(Authorization Code)
写在前面 1.源码(.Net Core 2.2) git地址:https://github.com/yizhaoxian/CoreIdentityServer4Demo.git 2.相关章节 2.1. ...
- Python自动化爬取App数据
基本环境配置 版本:Python3 系统:Windows 需要安装: 1.JDK - Download JDK,Appium要求用户必须配置JAVA环境, 否则启动Seesion报错. 很多人学习py ...
- Go语言入门系列(四)之map的使用
本系列前面的文章: Go语言入门系列(一)之Go的安装和使用 Go语言入门系列(二)之基础语法总结 Go语言入门系列(三)之数组和切片 1. 声明 map是一种映射,可以将键(key)映射到值(val ...
- Iconfont的代码使用
1.Iconfont官网 相关阅读: Iconfont-阿里巴巴矢量图标库 Iconfont-阿里巴巴矢量图标库-代码使用 2.下载代码 注意到把鼠标悬停到图标上,会出现三个按钮. 我们点击" ...
- 极简 Node.js 入门 - 1.4 NPM & package.json
极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...
- Bytom DAPP 开发流程
从目前已经发布的DAPP来看,DAPP架构大致可以分成3种类型:插件钱包模式.全节点钱包模式和兼容模式. 插件钱包模式是借助封装了钱包的浏览器插件通过RPC协议与区块链节点通信,插件在运行时会将Web ...