POJ 3254 Corn Fields

链接

思路

  状压dp,dp[i][j]:表示到第i行,状态为j的方案数。预处理出每一行所有的可能的选法。

  转移方程:dp[i][j] += d[i-1][k],j与k不冲突。

代码

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<cmath>
 6 
 7 using namespace std;
 8 
 9 const int mod = 1e9;
10 int a[15][15],sta[15][10010],dp[15][10010];
11 int n,m;
12 
13 inline int read() {
14     int x = 0,f = 1;char ch = getchar();
15     for (; !isdigit(ch); ch=getchar()) if(ch=='-') f=-1;
16     for (; isdigit(ch); ch=getchar()) x = x*10+ch-'0';
17     return x * f;
18 }
19 
20 void getsta() {
21     int t = (1 << m) - 1;bool flag;
22     for (int i=1; i<=n; ++i) {
23         for (int j=0; j<=t; ++j) {
24             flag = true;
25             for (int k=0; k<m; ++k) 
26                 if (!a[i][m-k] && ((1<<k)&j)) {flag = false;break;}
27             if (!flag) continue;
28             if (j & (j<<1)) continue;
29             sta[i][++sta[i][0]] = j;
30         }
31     }
32 }
33 void getdp() {
34     for (int i=1; i<=sta[1][0]; ++i) dp[1][i] = 1; //dp[1][i] not dp[1][sta[1][i]]
35     for (int i=2; i<=n; ++i) 
36         for (int j=1; j<=sta[i][0]; ++j) 
37             for (int k=1; k<=sta[i-1][0]; ++k) {
38                 if (sta[i][j] & sta[i-1][k]) continue;
39                 dp[i][j] += dp[i-1][k];
40                 if (dp[i][j] > mod) dp[i][j] %= mod;
41             }
42     int ans = 0;
43     for (int i=1; i<=sta[n][0]; ++i) {
44         ans += dp[n][i];
45         if (ans > 0) ans %= mod;
46     }
47     cout << ans;
48 }
49 
50 int main() {
51     n = read(),m = read();
52     for (int i=1; i<=n; ++i) 
53         for (int j=1; j<=m; ++j) 
54             a[i][j] = read();
55     getsta();
56     getdp();
57     return 0;
58 }

 

http://poj.org/problem?id=3254

posted @ 2018-04-27 22:00  MJT12044  阅读(132)  评论(0编辑  收藏  举报