状压DP总是让我绝望(蒟蒻噩梦)
所以我就想写一篇博客来总结一发。(每道例题在我的博客中都可以找到完整题解)
NO.1
其实有时候并不需要把状态中每个状态给表示出来,只要不影响状态之间的转移即可。
比如:
[USACO08NOV]奶牛混合起来Mixed Up Cows(在洛谷的题目)
[USACO08NOV解题报告]奶牛混合起来Mixed Up Cows(蒟蒻的完整解题报告)
题目描述
约翰家有N头奶牛,第i头奶牛的编号是Si,每头奶牛的编号都是唯一的。这些奶牛最近 在闹脾气,为表达不满的情绪,她们在挤奶的时候一定要排成混乱的队伍。在一只混乱的队 伍中,相邻奶牛的编号之差均超过K。比如当K = 1时,1, 3, 5, 2, 6, 4就是一支混乱的队伍, 而1, 3, 6, 5, 2, 4不是,因为6和5只差1。请数一数,有多少种队形是混乱的呢?
(1<=n<=16)
解法:
这道题我当初就是死在试图把每头牛的位置表示出来
但经过一番摸♂索,我发现,其实不需要知道每头牛的位置。
只需知道每头牛是否已经被选和最后一牛的是第几只
因为如果用刷表法DP,每次状态状态转移只会转移合法状态,所以其实并不需要关注牛内部的排序方式。
dp[j][i]表示第j头牛是最后一只,选牛的方案用二进制表示为i。
主要代码
1 | for(int i=0;i<(1<<n);++i)//枚举状态 |