农夫约翰的土地由 M×N 个小方格组成,现在他要在土地里种植玉米。
非常遗憾,部分土地是不育的,无法种植。
而且,相邻的土地不能同时种植玉米,也就是说种植玉米的所有方格之间都不会有公共边缘。
现在给定土地的大小,请你求出共有多少种种植方法。
土地上什么都不种也算一种方法。
输入格式
第 1 行包含两个整数 M 和 N。
第 2..M+1 行:每行包含 N 个整数 0 或 1,用来描述整个土地的状况,1 表示该块土地肥沃,0 表示该块土地不育。
输出格式
输出总种植方法对 108 取模后的值。
数据范围
1≤M,N≤12
输入样例:
2 3
1 1 1
0 1 0
输出样例:
9
题目思路:
状态压缩:
用二进制表示状态
用十进制数存储状态
1.每一行的所有状态。 !(i&i>>1)
2.前一行和当前行的状态。
状态表示
f[i][a] = (f[i][a] + f[i - 1][b])
题解代码:
#include<bits/stdc++.h>
using namespace std;
const int M = 1e9;
int n, m;
int g[14];
int cnt;
int s[1 << 14];
int f[14][1 << 14];
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
int x;
cin >> x;
g[i] = (g[i] << 1) + x;
}
}
for (int i = 0; i < (1 << m); i++) {
if (!(i & i >> 1)) {
s[cnt++] = i;
}
}
f[0][0] = 1;
for (int i = 1; i <= n + 1; i++) {
for (int a = 0; a < cnt; a++) {
for (int b = 0; b < cnt; b++) {
if ((s[a] & g[i]) == s[a] && !(s[a] & s[b])) {
f[i][a] = (f[i][a] + f[i - 1][b]) % M;
}
}
}
}
printf("%d\n", f[n + 1][0]);
return 0;
}