状压DP详解(位运算)
前言:
状压DP是一种非常暴力的做法(有一些可以排除某些状态的除外),例如dp[S][v]中,S可以代表已经访问过的顶点的集合,v可以代表当前所在的顶点为v。S代表的就是一种状态(二进制表示),比如 (11001)2 代表在二进制中{0,3,4}三个顶点已经访问过了,(11001)2 代表的十进制数就是25 ,所以当S为25的时候其实就是代表已经访问过了{0,3,4}三个顶点,那假如一共有5个顶点(标号为01234)的话,所有的顶点都访问完毕应该S为什么呢?是 (11111)2。
那么,在状态转移的过程中我们势必要对十进制数转化为二进制数的每一个的位数进行一些操作。下面,列举了一些位运算的操作。

对于上面的一些操作举例一些
就如之上的 (11001)2 来说是已经访问了0,3,4三个顶点,当我接下去要访问顶点2的话可以有以下操作:1.看看第3位是什么?那么选择取出二进制数x的第k位,y = x >>(k-1) & 1,y = (110)2 & 1 = 0,2.把第3位变为1,y = x | (1<<(k-1)),y = (11001)2 | (100)2 = (11101)2,所以顶点2访问完毕,加入到集合S中也结束了,此时S为(11101)2 = 29。
接下去就可以开始讲一些例题了。最经典的就是白皮书上的tsp问题。
tsp问题
题意:假设有一个旅行商人要拜访N个城市,他必须选择所要走的路径,路径的限制是每个城市 只能拜访一次,而且最后要回到原来出发的城市,要求路径的总和最小。其中,2<=N<=15
思路:首先我们试着去设计状态,假设现在已经访问过的顶点的集合为S,当前所在顶点为v, 用dp[S][v]表示从v出发还有访问剩余的所有顶点,最终返回到顶点0的路径总和最小值。从v出发可以到任意一个还未访问过的顶点,边界就是访问完所有顶点并且返回到顶点0。
递推式为
dp[V][0] = 0;(边界)
dp[S][v] = min{dp[S∪{u}][u] + d[u][v] | u不属于S}
先通过记忆化搜索来看一下code
// s: 已经访问过的节点状态 v: 出发位置
int dfs(int s, int v)
{
if(dp[s][v]>=)
return dp[s][v];
if(s==(<<n)- && v==) //已经访问过所有的节点并且再次回到了0起点
return dp[s][v]=;
int ans=INF;
for(int u=;u<n;u++)
if(!(s>>(u &))) // 如果u这位是0(代表没有走过的话)就走u这个节点
ans=min(ans, dfs(s | (<<u), u)+mp[v][u]); //dfs中第一个参数表示第u位变成1后的二进制数
return dp[s][v]=ans;
}
int main()
{
memset(dp, -, sizeof(dp));
printf("%d\n", dfs(, ));
return ;
}
但是在这个问题中,对于任意两个整数i和j,如果他们对应的集合满足S(i)包含于S(j),就有i<=j,因此我们可以写成循环的方式。
int dp[<<maxn][maxn]; void solve()
{
for(int S = ; S < <<n; S++)
{
fill(dp[S],dp[S]+n,INF); //初始化
}
dp[(<<n) - ][] = ; //边界条件
//之前的记忆化搜索转换为递推式
for(int S = (<<n) - ; S >= ; S--)
{
for(int v = ; v < n; v++)
{
for(int u = ; u < n; u++)
{
if(!(S>>u&)){ //如果u不属于S集合
dp[S][v] = min(dp[S][v],dp[S|<<u][u]+d[v][u]);
}
}
}
}
printf("%d\n",dp[][]);
}
这样子,一个状压DP的板子差不多就出来了。
状压DP详解(位运算)的更多相关文章
- 状态压缩dp 状压dp 详解
说到状压dp,一般和二进制少不了关系(还常和博弈论结合起来考,这个坑我挖了还没填qwq),二进制是个好东西啊,所以二进制的各种运算是前置知识,不了解的话走下面链接进百度百科 https://baike ...
- 状压DP详解+题目
介绍 状压dp其实就是将状态压缩成2进制来保存 其特征就是看起来有点像搜索,每个格子的状态只有1或0 ,是另一类非常典型的动态规划 举个例子:有一个大小为n*n的农田,我们可以在任意处种田,现在来描述 ...
- 状态压缩动态规划(状压DP)详解
0 引子 不要999,也不要888,只要288,只要288,状压DP带回家.你买不了上当,买不了欺骗.它可以当搜索,也可以卡常数,还可以装B,方式多样,随心搭配,自由多变,一定符合你的口味! 在计算机 ...
- Codeforces 895C - Square Subsets 状压DP
题意: 给了n个数,要求有几个子集使子集中元素的和为一个数的平方. 题解: 因为每个数都可以分解为质数的乘积,所有的数都小于70,所以在小于70的数中一共只有19个质数.可以使用状压DP,每一位上0表 ...
- luoguP6622 [省选联考 2020 A/B 卷] 信号传递(状压dp)
luoguP6622 [省选联考 2020 A/B 卷] 信号传递(状压dp) Luogu 题外话: 我可能是傻逼, 但不管我是不是傻逼, 我永远单挑出题人. 题解时间 看数据范围可以确定状压dp. ...
- 状压DP入门详解+题目推荐
在动态规划的题型中,一般叫什么DP就是怎么DP,状压DP也不例外 所谓状态压缩,一般是通过用01串表示状态,充分利用二进制数的特性,简化计算难度.举个例子,在棋盘上摆放棋子的题目中,我们可以用1表示当 ...
- 状压DP初探·总结
2018过农历新年这几天,学了一下状态压缩动态规划,现在先总结一下. 状态压缩其实是一种并没有改变dp本质的优化方法,阶段还是要照分,状态还是老样子,决策依旧要做,转移方程还是得列,最优还是最优, ...
- 状压入门--bzoj1087: [SCOI2005]互不侵犯King【状压dp】
Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上 左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行, ...
- 状压DP : [USACO06NOV]玉米田
玉米田 内存限制:128 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 农场主John新买了一块长方形的新牧场,这块牧场被划分成M行N列(1 ≤ M ≤ ...
随机推荐
- 如何找到Android app启动activity和页面元素信息
在实施app自动化的时候,我们需要知道app 的启动activity和页面元素信息,以此启动app和定位页面元素,那么如何在没有源码的情况下找打他们呢?当然是有好的工具啦,有Android sdk自带 ...
- eclipse中安装thymeleaf插件完成thymeleaf模板中自动代码提示功能
插件地址:https://github.com/thymeleaf/thymeleaf-extras-eclipse-plugin 页面有介绍如何使用:
- ASP.NET 上传图片到FTP
目录: 2.代码 3.参考资料 4.IIS环境FTP配置 5.使用虚拟目录注意Server.MapPath() 1. 项目介绍 建立FTP文件服务器与应用程序分开. 下面方法中的参数为Stream因为 ...
- 项目01-nginx模块
项目01-nginx模块 1.nginx介绍 nginx是一款高性能web服务器和反向代理服务器,在互联网项目中使用非常频繁,尤其其出色的性能以及轻量级进程占用,已经超过了apache的httpd服务 ...
- HCNA配置浮动静态路由
1.拓扑图 2.配置IP R1 Please press enter to start cmd line! ############ <Huawei> Dec ::-: Huawei %% ...
- HCNA配置telnet远程管理
1.拓扑图 说明:通过配置最终能通过R5 用telnet协议登陆到R4上并将R4改名为R44 2.R4配置 <Huawei>sys Enter system view, return us ...
- 运行npm update等命令出错后如何分析问题根源
我今天工作时,在当前前端项目工作目录下执行命令npm update 结果遇到如下错误:registry error parsing json npm ERR! Unexpected token < ...
- ios视图层次结构
原文:http://blog.csdn.net/xingboss3/article/details/7890238 UIView表示屏幕上的一块矩形区域,它在App中占有绝对重要的地位,因为IOS中几 ...
- P1089 津津的储蓄计划
题目描述 津津的零花钱一直都是自己管理.每个月的月初妈妈给津津300300元钱,津津会预算这个月的花销,并且总能做到实际花销和预算的相同. 为了让津津学习如何储蓄,妈妈提出,津津可以随时把整百的钱存在 ...
- 2017.11.9 如何利用JS做登陆验证界面
()案例----JavaScript实现输入验证 需要验证的表单输入域和要求 用户名不能为空,是否符合规定的格式 密码长度是否超过6,两次密码输入一致 邮箱地址:邮箱地址必须符合邮箱形式 ~~~注意提 ...