状压dp

炮兵阵地 棋盘类
对于某行,受前两行状态影响
提前预处理出每一行合法的状态,减少三行无效枚举

Mondriaan’s Dream 棋盘类
按行放置,1代表竖放,并占用下一行;0代表该行由上行延伸或横放
[ i − 1 , j ] [i-1 ,j] [i1,j] 状态为1,则 [ i , j ] [i,j] [i,j]状态必为0
[ i − 1 , j ] [i-1,j] [i1,j] 状态为0,则 [ i , j ] [i,j] [i,j]状态为1/0 :对于1竖放无限制,对于0横放需保证 连续0必为偶数
在转移时只需删去非法状态的转移即可

简单环 TSA问题
dp[i][j] i为二进制表示已走过的点,为现在到达了j点。
为防止重复计算,规定二进制第一个1为开始,但是顺逆重复,除以2去重

CF1209E2
行数很小,考虑状压表示当前行是否已经选取过最大值
然后转移就很简单了,只需要枚举列,然后枚举当前列状态,枚举列状态子集,然后转移,时间复杂度 O ( m n 3 n ) O(mn3^n) O(mn3n),明显过大
因为有效对答案产生贡献的列不超过 n n n个,所以只要将列排个序,枚举前 n n n列就行了,时间复杂度 O ( n 2 3 n ) O(n^23^n) O(n23n)

P3188 [HNOI2007] 梦幻岛宝珠
01背包,但是物品的重量很特殊,数据提示可以将每个物品表示为 a ⋅ 2 b a \cdot 2^b a2b的形式,常规枚举每个物品合并,现在考虑按位合并,对于每一位来说,这一位的物品重量可以看作 a a a,价格不变,然后我们可以先对这一位的所有物品做个01背包,因为 a < = 10 a<=10 a<=10,最大容量为10000。
然后按位再合并, f i , j = m a x ( f i − 1 , ( j − k ) ∗ 2 + ( ( W > > ( i − 1 ) ) & 1 ) + g i , k ) f_{i,j}=max(f_{i-1,(j-k)*2+((W>>(i-1)) \& 1)}+g_{i,k}) fi,j=max(fi1,(jk)2+((W>>(i1))&1)+gi,k)

你可能感兴趣的:(dp,动态规划,算法)