1. 程式人生 > >BZOJ 1725: [Usaco2006 Nov]Corn Fields牧場的安排

BZOJ 1725: [Usaco2006 Nov]Corn Fields牧場的安排

nbsp php text 一行 ace bsp field mem 余數

1725: [Usaco2006 Nov]Corn Fields牧場的安排

Time Limit: 5 Sec Memory Limit: 64 MB
Submit: 865 Solved: 626
[Submit][Status][Discuss]

Description

Farmer John新買了一塊長方形的牧場,這塊牧場被劃分成M列N行(1<=M<=12; 1<=N<=12),每一格都是一塊正方形的土地。FJ打算在牧場上的某幾格土地裏種上美味的草,供他的奶牛們享用。遺憾的是,有些土地相當的貧瘠,不能用來放牧。並且,奶牛們喜歡獨占一塊草地的感覺,於是FJ不會選擇兩塊相鄰的土地,也就是說,沒有哪兩塊草地有公共邊。當然,FJ還沒有決定在哪些土地上種草。 作為一個好奇的農場主,FJ想知道,如果不考慮草地的總塊數,那麽,一共有多少種種植方案可供他選擇。當然,把新的牧場荒廢,不在任何土地上種草,也算一種方案。請你幫FJ算一下這個總方案數。

Input

* 第1行: 兩個正整數M和N,用空格隔開

* 第2..M+1行: 每行包含N個用空格隔開的整數,描述了每塊土地的狀態。輸入的第i+1行描述了第i行的土地。所有整數均為0或1,是1的話,表示這塊土地足夠肥沃,0則表示這塊地上不適合種草

Output

* 第1行: 輸出一個整數,即牧場分配總方案數除以100,000,000的余數

Sample Input

2 3
1 1 1
0 1 0


Sample Output

9

輸出說明:

按下圖把各塊土地編號:

1 2 3
4

只開辟一塊草地的話,有4種方案:選1、2、3、4中的任一塊。開辟兩塊草地的話,有3種方案:13、14以及34。選三塊草地只有一種方案:134。再加把牧場荒廢的那一種,總方案數為4+3+1+1=9種。
總結:刷水題有利健康 dp[i][j]表示第i行狀態為j al[i]表示第i行全選的狀態 kept[i]表示狀態i是否滿足 然後統計最後一行的所有答案
#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e8;
int n, m, dp[15][(1 << 12) + 5], al[15], kept[(1 << 12) + 5];
int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= m; ++j) {
			int x; scanf("%d", &x);
			if(x) al[i] |= (1 << (j - 1));
		}
	}
	for (int i = 0; i < (1 << m) - 1; ++i)
		kept[i] = (!(i & (i << 1)) && !(i & (i >> 1)));
	dp[0][0] = 1;
	for (int i = 1; i <= n; ++i) {
		for (int j = 0; j < (1 << m) - 1; ++j) {
			if(kept[j] && (j & al[i]) == j)
			for (int k = 0; k < (1 << m) - 1; ++k) {
				if(!(k & j) && dp[i - 1][k])
				dp[i][j] = (dp[i][j] + dp[i - 1][k]) % MOD;
			}
		}
	} int ans = 0;
	for (int i = 0; i < (1 << m) - 1; ++i) {
		ans = (ans + dp[n][i]) % MOD;
	} printf("%d\n", ans);
	return 0;
}

  

BZOJ 1725: [Usaco2006 Nov]Corn Fields牧場的安排