首页 > 代码库 > POJ3254 Corn Fields 状态压缩DP
POJ3254 Corn Fields 状态压缩DP
题目大意是在一块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; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。