IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: 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个元素。

由此,我们在对整数的二进制位进行操作时,需要熟练掌握位运算的相关知识。这里给出状态压缩中常用的几个表达式:

判断一个数字x二进制第i位是否为1 
	mask&(1<<i)>0 
将一个数字x二进制第i位更改为1
	x|=(1<<i)
将一个数字x二进制第i位更改为0 
	x=x^(1<<i)
把一个数字二进制下最靠右的第一个1去掉
	x=x&(x-1) 
mask1是mask2的子集
	(mask1&mask2)==mask1
n个位置所占的位数
	(1<<n)-1

? ? ? ? 这里注意:位运算的运算级别非常低(甚至低于“==”),所以在使用位运算时可以说能加括号就加括号,不管括号是不是多余

状态操作

在进行状态压缩动态规划时,其基本思路同普通的DP没有太大区别,所以在进行状态转移时也要枚举各个状态,这就涉及到了对二进制表示状态时的操作(如对不同状态的枚举、遍历,子集枚举等)

1、枚举所有状态

for(int mask=1;mask<(1<<n);mask++)
{
    
}

2、枚举子集

? ? ? ? 以11(1011)为例:

int mask=11;//1011
for(int i=mask;i;i=(i-1)&mask)
{
	for(int j=3;j>=0;j--)//11的二进制位有4位,所以从3—0枚举所有二进制位
	{
		if((i>>j)&1) cout<<1;
		else cout<<0;	
	} 
	cout<<endl;
}

????????证明i=(i-1)&mask:? ? ? ??

?



状态压缩动态规划的本质其实还是动态规划,所以搞定了用二进制表示状态后,直接与状态规划的思路接轨即可。

直接上例题:



例题?

H. [Atcoder ABC187F] Close Group

? 题目描述

给定一个?N?个点,?M?条边的无向图, 题目中保证没有重边.点集标记为?1,2,3,....n. 第?i?条边连接两个点Ai?和?Bi。

删去任意多条边,求最少能把整个图划分成若干个满足以下条件的连通分量.

条件:连通分量中任意两个点?a,?b?(1 ≤?a?≤?b), 都有:?a,?b之间有一条直接相连的边.

输入格式

第一行输入两个整数?N?和?M

接下来输入M行,每行包含两个整数?Ai?和?Bi?表示?Ai?和?Bi?间建立了一条边

输出格式

输出一个整数表示答案

样例数据

input1

3 2
1 2
1 3

output1

2

input2

4 6
1 2
1 3
1 4
2 3
2 4
3 4

output2

1

input3

10 11
9 10
2 10
8 9
3 4
5 8
1 8
5 6
2 5
3 6
6 9
1 9

output3

5

input4

18 0

output4

18

样例解释

对于样例1:移除顶点 1 和 2 之间的边或 移除顶点 1 和 3 之间的边

数据规模与约定

(1≤n≤18\)

(1≤m≤N?(N?1)/2\)

时间限制:3s

空间限制:1024MB

?

?

?首先考虑状态的设计,因为整个图的状态是由多个符合题意的连通分量构成的,所以应该先把各个点集划分的方案求出来,再合并出更大的点集,由此可以想到枚举子集的状压DP。

状态:dp[mask]表示选出的点集状态时mask时,划分的连通分量的个数集合中的最小值,当i位取1时表示该点被选入点集,反之不在点集中。

初值:dp[0]=0,没有点的时候不需要划分

不妨对每个点u预处理出一个集合的状态,表示u可以到达的点的集合,记作fa[u],具体判断时,只需要关注mask里面包含的每个点是否都出现在fa[u]中,即

if((fa[u]&mask)==mask)

具体状态转移时,考虑把mask集合分割成两个子集,套用枚举子集的模板,枚举mask的每一个子集,若分割的一个子集为j,则另一个就是mask-j,所以状态转移方程就是

dp[mask]=min(dp[mask],dp[j]+dp[mask-j]);

具体代码如下:

#include<bits/stdc++.h>
using namespace std;
int qr()
{
	int x=0,f=0;char ch=0;
	while(!isdigit(ch)) {f|=ch=='-';ch=getchar();}
	while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return f? -x:x;
}
int n,m;
int dp[1<<20];
int fa[20];
void init()
{
	n=qr();m=qr();
	for(int i=0;i<n;i++)
		fa[i]|=(1<<i);
	for(int i=1;i<=m;i++)
	{
		int x,y;
		x=qr();y=qr();
		fa[y-1]|=(1<<(x-1));//注意点的下标问题,要上下匹配
		fa[x-1]|=(1<<(y-1));
	}
}
void work()
{
	memset(dp,10,sizeof(dp));
	dp[0]=0;
	for(int mask=0;mask<(1<<n);mask++)
	{
		bool flag=1;
		for(int j=0;j<n;j++)
		{
			if(((1<<j)&mask)==(1<<j)&&(fa[j]&mask)!=mask)
					flag=0; 
		}
		if(flag==1) dp[mask]=1;
		for(int j=mask;j;j=(mask&(j-1)))
		{
			dp[mask]=min(dp[mask],dp[mask-j]+dp[j]);
		}
	}
	cout<<dp[(1<<n)-1];
}
int main()
{
	init();
	work();
}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-07-21 21:45:58  更:2022-07-21 21:48:08 
 
开发: 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-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码