状态压缩DP
含义
是一种对状态表示形式的一种优化。
前置知识——常见的位操作
任何二进制数位;
&1
得到它本身。^1
则取反。&0
则赋值为 00。|1
则赋值为 11。
通常二进制的第一位我们称之为第零位。
(n>>k)&1
取出二进制下 nn 的第 kk 位(从右往左数)。n&((1<<k)-1)
去除二进制下 nn 的右 kk 位。n^(1<<k)
将二进制下 nn 的第 kk 位取反。n|(1<<k)
将二进制下 nn 的第 kk 位赋值为 11。n&(~(1<<k))
将二进制下 nn 的第 kk 位赋值为 00。
模板例题——P10447 最短 Hamilton 路径
见 https://www.luogu.com.cn/article/z883dedy。
前置知识——常用优先级
四则运算符 >> 位移运算符 >> 位运算符 >> 逻辑运算符。
例题
First:P1879
定义状态 dp_{i,j}dpi,j 表示前 ii 行且第 ii 行的种草状态为二进制下的 jj 的方案数。
答案为所有 dp_{m,j}dpm,j 的和对 100000000100000000 取模。
维护 soil_isoili 表示第 ii 行的肥沃情况。当种草状态 j \& soil_i = jj&soili=j,种草在肥沃土地上。
上下中草的两个状态按位与的结果为 00 时,不冲突。
种草状态 ii 左移 11 位后再和 ii 按位与的结果为 00 时,不冲突。
初始状态:dp_{0,0}=1dp0,0=1
状态转移除了判肥沃以外还是有点板的。
Second:P2704 炮兵阵地
定义状态为 dp_{i,j,k}dpi,j,k 表示前 ii 行且第 ii 行状态为二进制下的 jj,第 i-1i−1 行的状态为二进制下的 kk 的最大炮兵数。
答案即为 dp_{n,j,k}dpn,j,k 的最大值。
状态转移稍有点ex。
提示:需要维护一个 soil_isoili,soil[i]=(soil[i]<<1)+(c=='P');
。
初始状态:dp_{0,0}=0dp0,0=0,其余 极小值。
优化:滚动数组、提前筛可能状态。
有Latex版请在安全访问中心 - 洛谷查看