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)详解的更多相关文章

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

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

  2. 状态压缩dp 状压dp 详解

    说到状压dp,一般和二进制少不了关系(还常和博弈论结合起来考,这个坑我挖了还没填qwq),二进制是个好东西啊,所以二进制的各种运算是前置知识,不了解的话走下面链接进百度百科 https://baike ...

  3. 状压DP详解+题目

    介绍 状压dp其实就是将状态压缩成2进制来保存 其特征就是看起来有点像搜索,每个格子的状态只有1或0 ,是另一类非常典型的动态规划 举个例子:有一个大小为n*n的农田,我们可以在任意处种田,现在来描述 ...

  4. 状压DP详解(位运算)

    前言: 状压DP是一种非常暴力的做法(有一些可以排除某些状态的除外),例如dp[S][v]中,S可以代表已经访问过的顶点的集合,v可以代表当前所在的顶点为v.S代表的就是一种状态(二进制表示),比如 ...

  5. hihoCoder 1044 : 状态压缩·一 状压dp

    思路:状态压缩,dp(i, j)表示考虑前i个数且[i-m+1, i]的选择情况为j.如果要选择当前这个数并且,数位1的个数不超过q,则dp[i+1][nex] = max(dp[i+1][nex], ...

  6. hihocoder #1044 : 状态压缩·一 状压DP

    http://hihocoder.com/problemset/problem/1044 可以看出来每一位的选取只与前m位有关,我们把每个位置起始的前m位选取状态看出01序列,就可以作为一个数字来存储 ...

  7. 动态规划---状压dp

    状压dp,就是把动态规划之中的一个个状态用二进制表示,主要运用位运算. 这里有一道例题:蓝书P639猛兽军团1 [SCOI2005]互不侵犯 题目: 题目描述 在N×N的棋盘里面放K个国王,使他们互不 ...

  8. 【bzoj3195】【 [Jxoi2012]奇怪的道路】另类压缩的状压dp好题

    (上不了p站我要死了) 啊啊,其实想清楚了还是挺简单的. Description 小宇从历史书上了解到一个古老的文明.这个文明在各个方面高度发达,交通方面也不例外.考古学家已经知道,这个文明在全盛时期 ...

  9. 【状压DP】bzoj1087 互不侵犯king

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

随机推荐

  1. activiti7 获取流程定义的xml

    RepositoryService repositoryService = ProcessEngines.getDefaultProcessEngine().getRepositoryService( ...

  2. 自述:转职IT ,痛苦一阵子;不转职IT,痛苦一辈子(第一章)

    作为一个从后期制作转职过来的Java工程师,我认为我是幸运的,虽然我的本科专业(影视后期)也是火爆行业,不愁工作,但我不后悔进入这个IT坑,毕竟转行,只痛苦一阵子,但是不转行,可能我会痛苦一辈子. 我 ...

  3. PHP scandir() 函数

    ------------恢复内容开始------------ 实例 列出 images 目录中的文件和目录: <?php$dir = "/images/"; // Sort ...

  4. PHP atanh() 函数

    实例 返回不同数的反双曲正切: <?phpecho(atanh(M_PI_4) . "<br>");echo(atanh(0.50) . "<br ...

  5. PHP getNamespaces() 函数

    实例 返回 XML 文档中使用的命名空间: <?php$xml=<<<XML高佣联盟 www.cgewang.com<?xml version="1.0&quo ...

  6. 记录一次线上实施snmp

    公司要实施一个部级的项目,我们公司的提供的产品要对接下客户的一个平台监控平台,该监控平台使用snmp,我们公司的产品不支持snmp,所以由我负责在现网实施snmp,记录这次现网 一.生成编译规则 1. ...

  7. 配置ssh互信

    配置基于密钥认证的免密登录 用到的命令: ssh-keygen:创建公钥和密钥,会生成id_rsa和id_rsa.pub两个文件 生成ssh密钥后,密钥将默认存储在家目录下的.ssh/目录中.私钥和公 ...

  8. 使用ProxySQL实现MySQL Group Replication的故障转移、读写分离(二)

    在上一篇文章<使用ProxySQL实现MySQL Group Replication的故障转移.读写分离(一) > 中,已经完成了MGR+ProxySQL集群的搭建,也测试了ProxySQ ...

  9. DataGrip 2020.1 安装与激活

    1 软件下载 百度网盘: 链接:https://pan.baidu.com/s/1kHSq1XS0i4YDF0HuzsxCLg 提取码:djyc 2 安装 解压文件后点击 datagrip-2020. ...

  10. Java日志框架(一)

    在项目开发过程中,我们可以通过 debug 查找问题.而在线上环境我们查找问题只能通过打印日志的方式查找问题.因此对于一个项目而言,日志记录是一个非常重要的问题.因此,如何选择一个合适的日志记录框架也 ...