[状压DP]luogu P6622 [省选联考 2020 A/B 卷] 信号传递
题面
https://www.luogu.com.cn/problem/P6622
分析
枚举每个信号塔的位置显然不行,考虑设置 DP 状态
f[S] 表示选择了集合为 S 的塔,排在前 |S| 个位置
方程则为 $f[S|i]=f[S]+h[S,i]$ $h[S,i]$ 表示 S 中与 i 有连边的贡献
$h[S,i]$ 怎么求呢?据题意有
$w_{i,j}=j-i (i $w_{i,j}=ki+kj (i>j)$ 发现可以对于每个位置来计算贡献,有一条向后的出边则 -1 ,向前的出边则 +k ,从后来的入边则 +k ,从前来的入边则 +1 设 $c_{i,j}$ 为 i 到 j 的边数,则有 $h[S,i]=(|S|+1)\times(\sum_{j\in S}(kc_{i,j}+c_{j,i}) + \sum_{j\notin S|i}(kc_{j,i}+c_{i,j}))$ 这样时间复杂度是 $O(m^22^m)$ 的,如果从低位往高位枚举 S 并同时转移 h[S,i] ,则可以压到 $O(m2^m)$ 但是空间复杂度仍然不足以AC,瓶颈在于 h[S,i] 发现如果从小往大枚举,那么最近枚举的一个位数为 i 的状态 S 枚举到下一个位数为 i 的状态 S' 之前一定会枚举到一个位数为 i+1 的状态 S'' ,而 S'' 显然为 S+lowbit(S) 所以可以直接改为 h[|S|,i] ,每次转移的时候从 h[|S|-1,i] 加上对应贡献即可代码
#include