【算法详解】状态压缩DP

本文详细介绍了如何使用二进制状态压缩解决动态规划问题,包括最短Hamilton路径、关灯问题以及USACO竞赛中的玉米田问题。通过实例展示了如何设置状态、进行位运算,并给出了相应的解决方案和时间复杂度分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于状态压缩

对于某些题目,一般的DP无法正常解决,例如过程的设置较为复杂,状态的枚举效率不够高或无法利用一般的数组完成,这时候就要用到二进制状态压缩来利用内部二进制的特性来简单的表达状态。

由于和二进制结合起来,状态压缩的DP一般效率较高,因为需要用二进制的每一位来表示每一个状态,所以往往复杂度中含有2n2^n2n项,因此状态压缩的题目nnn一般不大于202020.

如果要熟练的运用二进制的状态压缩,我们要学会使用位运算。

位运算

首先要熟悉and/&,or/∣,not/!and/\&,or/|,not/!and/&,or/,not/!的操作。

下面有一些基本的操作:
1.将x去掉最后一位数:x=x>>1x=x>>1x=x>>1
2.将x的末尾加上0:x=x&lt;&lt;1x=x&lt;&lt;1x=x<<1
3.将x的第k位变成0:x=x&amp;(not(1&lt;&lt;k−1))x=x\&amp;(not(1&lt;&lt;k-1))x=x&(not(1<<k1))
4.将x的第k位变成1:x=x∣(1&lt;&lt;k−1)x=x|(1&lt;&lt;k-1)x=x(1<<k1)
5.x的第k位数字为:1&amp;(x&gt;&gt;k−1)1\&amp;(x&gt;&gt;k-1)1&(x>>k1)
6.将x的第k位取反:x=x xor (1&lt;&lt;k−1)x=x\ xor\ (1&lt;&lt;k-1)x=x xor (1<<k1)
7.x位的每一位都位1的数:(1&lt;&lt;x)−1(1&lt;&lt;x)-1(1<<x)1
8.判断第x位是否在状态p中,在表示0,不在表示1:p&amp;(1&lt;&lt;x−1)p\&amp;(1&lt;&lt;x-1)p&(1<<x1)
具体还有这一些:
在这里插入图片描述

最短Hamilton路径

题目描述
给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径。 Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每个点恰好一次。
输入和输出
Input
第一行一个整数n。 接下来n行每行n个整数,其中第i行第j个整数表示点i到j的距离(一个不超过10^7的正整数,记为a[i,j])。 对于任意的x,y,z,数据保证 a[x,x]=0,a[x,y]=a[y,x] 并且 a[x,y]+a[y,z]>=a[x,z]。
Output
一个整数,表示最短Hamilton路径的长度。
样例
Sample Input

4
0 2 1 3
2 0 2 1
1 2 0 1
3 1 1 0
Sample Output
4
数据规模与约定
时间限制:1s
空间限制:256MB

solution

对于这道题,显然要用状态压缩在设置状态。

可以设f[i][j]f[i][j]f[i]

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值