关于状态压缩
对于某些题目,一般的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<<1x=x<<1x=x<<1
3.将x的第k位变成0:x=x&(not(1<<k−1))x=x\&(not(1<<k-1))x=x&(not(1<<k−1))
4.将x的第k位变成1:x=x∣(1<<k−1)x=x|(1<<k-1)x=x∣(1<<k−1)
5.x的第k位数字为:1&(x>>k−1)1\&(x>>k-1)1&(x>>k−1)
6.将x的第k位取反:x=x xor (1<<k−1)x=x\ xor\ (1<<k-1)x=x xor (1<<k−1)
7.x位的每一位都位1的数:(1<<x)−1(1<<x)-1(1<<x)−1
8.判断第x位是否在状态p中,在表示0,不在表示1:p&(1<<x−1)p\&(1<<x-1)p&(1<<x−1)
具体还有这一些:
最短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]