| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> 状态压缩动态规划 -> 正文阅读 |
|
[数据结构与算法]状态压缩动态规划 |
状态压缩类动态规划,顾名思义,其核心就是在于对状态表达进行压缩。 在动态规划中,重点、难点更是突破点所在,就是阶段划分过后的状态表达及转移。在一般动态规划中,如果要维护一个集合的状态,常常用int 或bool类型的数组进行表达与描述。如果这个集合包含的元素个数很少,我们就把描述集合状态的数组压缩到一个整数中,这种用一个整数来描述一个集合的方法就叫作“状态压缩”。而当状态的某个维度存储的是一个集合的状态,这类问题就称作:状态压缩动态规划。 如果集合中每个元素的状态只有两种,我们一般用1和0进行描述,因此当我们用一个整数表达时,就自然而然地与二进制相对应。也就是说我们可以用一个整数对应的二进制位来表示集合中元素的状态。(如果状态有三种就采用三进制,以此类推) 比如给定一个整数23,它所对应的的二进制数为10111,那么我们就可以认为这个集合中包含了第1、2、3、5这些元素,而不包括第4个元素。 由此,我们在对整数的二进制位进行操作时,需要熟练掌握位运算的相关知识。这里给出状态压缩中常用的几个表达式:
? ? ? ? 这里注意:位运算的运算级别非常低(甚至低于“==”),所以在使用位运算时可以说能加括号就加括号,不管括号是不是多余 状态操作在进行状态压缩动态规划时,其基本思路同普通的DP没有太大区别,所以在进行状态转移时也要枚举各个状态,这就涉及到了对二进制表示状态时的操作(如对不同状态的枚举、遍历,子集枚举等) 1、枚举所有状态
2、枚举子集? ? ? ? 以11(1011)为例:
????????证明i=(i-1)&mask:? ? ? ?? ?状态压缩动态规划的本质其实还是动态规划,所以搞定了用二进制表示状态后,直接与状态规划的思路接轨即可。 直接上例题: 例题?
?首先考虑状态的设计,因为整个图的状态是由多个符合题意的连通分量构成的,所以应该先把各个点集划分的方案求出来,再合并出更大的点集,由此可以想到枚举子集的状压DP。 状态:dp[mask]表示选出的点集状态时mask时,划分的连通分量的个数集合中的最小值,当i位取1时表示该点被选入点集,反之不在点集中。 初值:dp[0]=0,没有点的时候不需要划分 不妨对每个点u预处理出一个集合的状态,表示u可以到达的点的集合,记作fa[u],具体判断时,只需要关注mask里面包含的每个点是否都出现在fa[u]中,即
具体状态转移时,考虑把mask集合分割成两个子集,套用枚举子集的模板,枚举mask的每一个子集,若分割的一个子集为j,则另一个就是mask-j,所以状态转移方程就是
具体代码如下:
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 23:51:23- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |