嘟嘟嘟

 

看来状压dp入门题都是这个难度的。

令dp[i][j]表示到了第 i 行,状态为 j 时的方案数。

然后枚举这一行和上一行的状态,则dp[i][j] += dp[i - 1][k]。

预处理合法的种植状态。

还有,判断种植状态符不符合草地状态只能一位一位比较,因为位运算不能辨别两个数的二进制,只能得出他们的运算结果。

POJ 3254. Corn Fields_C  教程POJ 3254. Corn Fields_编程开发_02
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<cctype>
 8 #include<vector>
 9 #include<stack>
10 #include<queue>
11 using namespace std;
12 #define enter puts("") 
13 #define space putchar(' ')
14 #define Mem(a) memset(a, 0, sizeof(a))
15 typedef long long ll;
16 typedef double db;
17 const int INF = 0x3f3f3f3f;
18 const db eps = 1e-8;
19 const int mod = 1e8;
20 const int max_sta = 400;
21 inline ll read()
22 {
23     ll ans = 0;
24     char ch = getchar(), last = ' ';
25     while(!isdigit(ch)) {last = ch; ch = getchar();}
26     while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
27     if(last == '-') ans = -ans;
28     return ans;
29 }
30 inline void write(ll x)
31 {
32     if(x < 0) x = -x, putchar('-');
33     if(x >= 10) write(x / 10);
34     putchar(x % 10 + '0');
35 }
36 
37 int n, m;
38 int Map[15], s[max_sta], sum[max_sta], cnt = 0;
39 ll dp[15][max_sta];
40 
41 bool judge(int a, int b)
42 {
43     for(int i = 0; i < m; ++i)
44         if(!(a & (1 << i)) && (b & (1 << i))) return 0;
45     return 1;
46 }
47 
48 int getsum(int x)
49 {
50     int ret = 0;
51     for(; x; x >>= 1) ret += x & 1;
52     return ret;
53 }
54 void init()
55 {
56     for(int i = 0; i < (1 << m); ++i)
57         if(!(i & (i << 1)) && !(i & (i >> 1)))
58         {
59             s[++cnt] = i;
60             if(judge(Map[1], i)) dp[1][cnt]++;
61         }
62 }
63 
64 int main()
65 {
66     n = read(); m = read();
67     for(int i = 1; i <= n; ++i)
68         for(int j = 0; j < m; ++j)
69         {
70             int x = read();
71             Map[i] |= x << j;
72         }
73     init();
74     for(int i = 2; i <= n; ++i)
75         for(int j = 1; j <= cnt; ++j) if(judge(Map[i], s[j]))
76             for(int k = 1; k <= cnt; ++k) if(judge(Map[i - 1], s[k]) && !(s[k] & s[j]))
77                 (dp[i][j] += dp[i - 1][k]) %= mod;
78     ll ans = 0;
79     for(int i = 1; i <= cnt; ++i) (ans += dp[n][i]) %= mod;
80     write(ans); enter;
81     return 0;
82 }
View Code