题目大意是在一块M行N列的农场上种谷物,但是不希望彼此相邻(共用一条边),并且有些地方不能种植谷物,给定M,N(范围都不超过12)以及一些不能种谷物的位置,求出一共有多少种方法种谷物。
状态压缩DP,设dp(i, k) 为种到第i行时,第i行状态为k的总共方案数,可以知道dp(i, k) = ∑dp(i -1, k‘),其中我们要判断彼此相邻的情况以及不能种植的情况即可。
#include <stdio.h> #include <vector> #include <math.h> #include <string.h> #include <string> #include <iostream> #include <queue> #include <list> #include <algorithm> #include <stack> #include <map> #include <time.h> using namespace std; int dp[13][5000]; int planted[12][12]; int main() { #ifdef _DEBUG freopen("e:\\in.txt", "r", stdin); #endif memset(dp, 0, sizeof(dp)); memset(planted, 0, sizeof(planted)); int n, m; scanf("%d %d", &n, &m); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { scanf("%d", &planted[i][j]); } } int count = 1; dp[0][0] = 1; for (int i = 1; i <= n; i++) { for (int k = 0; k < (1 << m); k++) { for (int j = 0; j < (1 << m); j++) { bool bok = true; for (int c = 0; c < m;c++) { if (((k >> c) & 1) == 1 && (((j >> c) & 1) == 1 || planted[i-1][c] == 0)) { bok = false; break; } if (c > 0) { if (((k >> c) & 1) == 1 && ((k >> (c - 1)) & 1) == 1) { bok = false; break; } } if (c < m - 1) { if (((k >> c) & 1) == 1 && ((k >> (c + 1)) & 1) == 1) { bok = false; break; } } } if (!bok) { continue; } dp[i][k] += dp[i - 1][j]; dp[i][k] %= 1000000000; } if (k!=0) { count += dp[i][k]; count %= 1000000000; } } } printf("%d\n", count); return 0; }
POJ3254 Corn Fields 状态压缩DP,布布扣,bubuko.com
原文地址:http://blog.csdn.net/u011363774/article/details/38342771