农夫约翰的土地由M*N个小方格组成,现在他要在土地里种植玉米。
非常遗憾,部分土地是不育的,无法种植。
而且,相邻的土地不能同时种植玉米,也就是说种植玉米的所有方格之间都不会有公共边缘。
现在给定土地的大小,请你求出共有多少种种植方法。
土地上什么都不种也算一种方法。
输入格式
第1行包含两个整数M和N。
第2…M+1行:每行包含N个整数0或1,用来描述整个土地的状况,1表示该块土地肥沃,0表示该块土地不育。
输出格式
输出总种植方法对100000000取模后的值。
数据范围
1≤M,N≤121≤M,N≤12
输入样例:
2 3
1 1 1
0 1 0
输出样例:
9
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 14, M = 1 << 12, mod = 1e8;
int n, m;
vector<int> state;
vector<int> head[M];
int f[N][M];
int w[N];
bool check(int state){
for (int i = 0; i + 1 < m; i ++)
if ((state >> i & 1) && (state >> i + 1 & 1))
return false;
return true;
}
int main(){
cin >> n >> m;
for (int i = 1; i <= n; i ++)
for (int j = 0; j < m; j ++){
int t;
scanf("%d", &t);
w[i] += !t << j;
}
for (int i = 0; i < 1 << m; i ++)
if (check(i))
state.push_back(i);
for (int i = 0; i < state.size(); i ++)
for (int j = 0; j < state.size(); j ++){
int a = state[i], b = state[j];
if (!(a & b)) head[i].push_back(j);
}
f[0][0] = 1;
for (int i = 1; i <= n + 1; i ++)
for (int j = 0; j < state.size(); j ++){
if (!(state[j] & w[i])){
for (int k : head[j])
f[i][j] = (f[i][j] + f[i - 1][k]) % mod;
}
}
cout << f[n + 1][0] << endl;
return 0;
}