以前从未尝试过写一个知识点,emmm可能是懒得一个个写了叭。
状压dp就是将储存很耗空间的东西转成2进制(用1与0表示状态),再转成10进制储存。(其实感觉也对bfs挺适用的)
来几道题便于理解:
【T1】国王
#include<cstdio>
int n, k, len, tmp;
long long sum, sta[1028], king[1028], dp[12][1028][103];
void init() {
int wei = (1 << n) - 1;//A
for(int i = 0; i <= wei; i ++) {
if(i & (i >> 1))//B
continue;
sta[++ len] = i;
tmp = i;
while(tmp) {
king[len] += tmp % 2;
tmp >>= 1;
}
}
}
int main() {
scanf("%d %d", &n, &k);
init();
for(int i = 1; i <= len; i ++)
if(king[i] <= k)
dp[1][i][king[i]] = 1;
for(int i = 2; i <= n; i ++) {
for(int j = 1; j <= len; j ++) {
for(int u = 1; u <= len; u ++) {
if(sta[j] & sta[u])
continue;
if((sta[j] << 1) & sta[u])
continue;
if(sta[j] & (sta[u] << 1))//C
continue;
for(int s = 0; s <= k; s ++)
if(king[j] + s <= k)
dp[i][j][king[j] + s] += dp[i - 1][u][s];
}
}
}
for(int j = 1; j <= len; j ++)
sum += dp[n][j][k];
printf("%lld\n", sum);
return 0;
}
先解释一波…
A:2进制表示放不放国王,则一个状态是有n位的,考虑到有0这一位,则减一。(正好为0~n-1的1【最大情况】)
B:这个地方左移和右移都没什么问题,判断一排有没有相邻的国王。
C:同B,判断上下,斜上下的国王。
【T2】玉米田
其实这题还要简单一点,只是要讲一个关于2进制的优化。
#include<cstdio>
const int mod = 1e8;
int n, m, check[14], len;
long long sta[4099], dp[14][4099], sum;
void init() {
int wei = (1 << m) - 1;
for(int i = 0; i <= wei; i ++) {
if(i & (i << 1))
continue;
sta[++ len] = i;
}
}
int main() {
int o, wei;
scanf("%d %d", &n, &m);
init();
for(int i = 1; i <= n; i ++) {
//wei = 1 << m - 1;
for(int j = 1; j <= m; j ++) {
scanf("%d", &o);
//check[i] += wei * o;
//wei >>= 1;
check[i] = (check[i] << 1) + o;
}
}
for(int i = 1; i <= len; i ++)
if((sta[i] & check[1]) == sta[i])
dp[1][i] = 1;
for(int i = 2; i <= n; i ++) {
for(int j = 1; j <= len; j ++) {
for(int k = 1; k <= len; k ++) {
if(sta[j] & sta[k])
continue;
if((sta[j] & check[i]) != sta[j])
continue;
dp[i][j] = (dp[i][j] + dp[i - 1][k]) % mod;
}
}
}
for(int i = 1; i <= len; i ++)
sum = (sum + dp[n][i]) % mod;
printf("%lld\n", sum);
return 0;
}
当题目给出可种范围时,学状压dp之前的我的第一想法肯定是暴力将范围与我选择的情况一一对比,然而我们有‘&’这种神奇的运算符——我们发现,在‘&’之后,如果结果与原先选择的情况相等,代表可种。(只要一个不可种,即check位是0,结果也是0,则不同了)
这里给出两种预处理check数组的写法。
如果有不对的地方,请大佬们在评论区落座呀。