状态压缩dp
所谓状态压缩,就是利用二进制位运算快的特点,用 0/1 表示是否已选,进行动态规划的一种算法.
一般能够应用状压 dp 的题目数据范围一般较小,一般在 20~40 之间.
基本操作:
1<<i-1:找到第i位并将其状态更新为 1;
S&(1<<i-1):找到状态 S 中第i位状态是否为 1;
S^(1<<i-1):找到状态 S 中第i位状态并将其取反.
例题:特殊方格棋盘
在n*n(n≤20)的方格棋盘上放置n 个车,某些格子不能放,求使它们不能互相攻击的方案总数.
一行一行来. 把每一行的是否放置作为状态,已经放表示为 1,没有则为 0. 使用 20 个数字,每个数字代表一行的状态.
设 dp[S] 为到达状态 S 所需的方案数.
由于我们发现,棋子是一行一行去放置的. 所以一个状态必然会由它的子状态贡献而来.
lowbit(x) 是将 x 中的最后一位 1 获得到. 其计算式为 x&-x,其实很好证明,拿计算器看一下二进制你就知道了.
那么就挨个去掉 1,然后再补回来呗.
那么代码很好写啦.
#define lowbit(x) (x&-x)
#define maxn 20
ll dp[1<<maxn];
int main()
{
n=read(); dp[0]=1;
for(rll S=1;S<1<<n;S++)
for(rll T=i;~T;T--)
dp[S]+=dp[S&~lowbit(T)];
write(dp[(1<<n)-1]);
}
--END--

浙公网安备 33010602011771号
我的博客: 𝟷𝙻𝚒𝚞
本文链接: https://www.cnblogs.com/1Liu/articles/16777444.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!