1. 程式人生 > >POJ 3254 Corn Fields

POJ 3254 Corn Fields

處理 lan 狀壓 預處理 lds cor ret poj 3254 class

鏈接

思路

  狀壓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

POJ 3254 Corn Fields