327. 玉米田

农夫约翰的土地由 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;
}

猜你喜欢

转载自blog.csdn.net/zhi6fui/article/details/128559334