[USACO06NOV] Corn Fields G
[USACO06NOV] Corn Fields G
状压 \(DP\) 板子题, 也是我的第一道状压 \(DP\) .
设 \(f[i][j]\) 为第 \(i\) 行状态为 \(j\) 时的方案数, 则上下两行没有相邻的用 \(j \& k == 0\) 来判, 同一行没有相邻的用 \(k << 1 \& k == 0 \&\& k >> 1 \& k == 0\) 来判.
\(code:\)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int read() {
int x = 0, f = 1;
char ch = getchar();
while (!isdigit(ch)) {
if (ch == '-') f = -1;
ch = getchar();
}
while (isdigit(ch)) {
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
const int mod = 1e8;
int n, m, f[15][1 << 12], s[15];
int main() {
n = read(), m = read();
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
s[i] = (s[i] << 1) + read();
}
}
f[0][0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 0; j < (1 << m); j++) {
for (int k = 0; k < (1 << m); k++) {
if (!(k & j) && (s[i] & k) == k && !(k << 1 & k) && !(k >> 1 & k)) {
f[i][k] += f[i - 1][j];
if (f[i][k] >= mod) f[i][k] -= mod;
}
}
}
}
int ans = 0;
for (int i = 0; i < (1 << m); i++) {
ans += f[n][i];
if (ans >= mod) ans -= mod;
}
printf("%d", ans);
return 0;
}
看不见我看不见我看不见我