ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

状压dp(总结)状态压缩

2021-03-08 14:01:25  阅读:501  来源: 互联网

标签:状态 二进制 压缩 状压 取反 long dp


状压这个和二进制分不开关系

所以,对于二进制的熟悉是必不可少的技能

&  与操作,1不变,0变0    

|  或操作,0不变,1变1  

^  异或操作,0不变,1取反   

~ 取反操作,把每一个二进制位0变1,1变0

还有一些复杂操作可以根据这些去理解

状态压缩

所谓状态压缩就是把dp的每一次转移时的状态用二进制来表示

或者用二进制来间接表示

比如

这里有10个苹果,编号1-10

我拿走了1,4,7,9这四个苹果

那么我们可以用011011010这一串二进制数来表示现在的状态

0表示这个位置没有苹果,1表示有

那么这就是一个状态

相比拿一个bool型的数组,这样表示更方便,内存更小,操作更简单

现在我想把拿走的苹果放回去,没拿走的拿走

那么状态就变成100100101

直接取反      a=011011010   b=100100101

a==~b;

这时候就充分展示了状态压缩的快捷性

下面我们讲一道例题。。。。。

在n*n(n≤20)的方格中放置n个车,每个车可以攻击所在的行和列,求方案总数

直接上排列组合,n!,很好理解啊

在n*n(n≤20)的方格棋盘上放置n 个车,某些格子不能放,求使它们不能互相攻击的方案总数。

这时候一些格子不能放,就要考虑每一行的情况

但是   ,,,,即使每一行中有的格子不能放,最终还是每一行每一列都要有一个车子

所以我们用s这个int型的数来表示现在的状态(行状态)

如果这一列现在有车子,那这一位就是1

所以最终s一定会变成11111111111(全是1)只有这样才能把n个车全部放进去

这样这一状态有几个车子说明这就是第几行

那这样转移方程就有了

dp[s]+=dp[s^(s&-s)];

for(;j>0;j-=(j&-j)){
    dp[i]+=dp[i^(j&(-j))];
}

还有个问题,有些格子不能放车

这怎么办???????????

还记得前面的苹果吗

用1表示这里能放车子,0表示不可以

在状态转移的时候&一下就可以啦

j=i&s[num];

代码如下

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m;
long long dp[1<<20];
int s[25];
int main(){
	memset(s,0x7fffffff,sizeof(s));
	//if(s[1][1]==1)cout<<"sh";
	//cout<<(s[1][1]&0)<<endl;
	scanf("%d%d",&n,&m);
	int x,y;
	for(int i=1;i<=m;i++){
		scanf("%d%d",&x,&y);
		s[x]-=(1<<(y-1));
	}
	dp[0]=1;
	for(int i=1;i<(1<<n);i++){
		int j,num=0;
		for(j=i;j>0;j-=(j&(-j))){
			num++;
		}
		j=i&s[num];
		for(;j>0;j-=(j&-j)){
			dp[i]+=dp[i^(j&(-j))];
		}
	}
	printf("%lld",dp[(1<<n)-1]);
}

 这样基本的状压dp就结束了

也许你已经发现了

所有的n都小于等于20

因为int只有32位

这也是状压的前提

所以当你一直为空间时间复杂度着急时

就去考虑状压

而状压前先找到可以状压的数

就是32位以内的

over

标签:状态,二进制,压缩,状压,取反,long,dp
来源: https://www.cnblogs.com/fengwu2005/p/14495183.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有