題目連結:http://poj.org/problem?id=3254
題意:
給你一片n*m的耕地,你可以在上面種玉米。但是其中有一些地方是荒蕪的,不能種植。並且種植玉米的地方不能相鄰。問你在這片地上有多少種種植方案。
題解:
思路:一行一行種
狀態表示:
dp[state][i] = num of ways at ith row
(1)當前種到了第i行
(2)第i行有哪些地方種了玉米,狀態為state
如何轉移:
約束條件:
(1)對於當前行,已經在某些地方種過了玉米,那麼在下一行的對應位置就不能再種。
(2)在每一行內部,種植玉米不能相鄰。
所以可以預處理(dfs)出在一行上每一種state對應的下一行可以種的方案nex。
轉移條件:
(1)state在當前第i行合法。
(2)state對應的nex在i+1行合法。
所以在讀入的時候,就可以預處理出每一行土地的情況field[i]。二進位制下每一位0代表可以種,1代表不能種。
以上兩個條件就變成了:(state&field[i])==0 和 (nex&field[i+1])==0
轉移:
三重for迴圈,列舉種到第i行、當前行的種植方案state、state對應的下一行的種植方案nex。
dp[state|nex][i+1] += dp[state][i]
AC Code:
1 // optimizations: 2 // 1) a state is legal at a row only if: state&field == 0 3 // 2) preprocess the states can be transfered from another state 4 5 #include <iostream> 6 #include <stdio.h> 7 #include <string.h> 8 #include <vector> 9 #define MAX_N 15 10 #define MAX_S (1<<14) 11 #define MOD 100000000 12 13 using namespace std; 14 15 int n,m; 16 int ans; 17 int field[MAX_N]; 18 int dp[MAX_S][MAX_N]; 19 vector<int> transfer[MAX_S]; 20 21 void read() 22 { 23 memset(field,0,sizeof(field)); 24 cin>>n>>m; 25 int temp; 26 for(int i=0;i<n;i++) 27 { 28 for(int j=0;j<m;j++) 29 { 30 cin>>temp; 31 field[i]<<=1; 32 field[i]|=(!temp); 33 } 34 } 35 field[n]=(1<<m)-1; 36 } 37 38 void dfs(int col,int state,int nex) 39 { 40 if(col>=m) 41 { 42 transfer[state].push_back(nex); 43 return; 44 } 45 if(!((state>>col)&1)) dfs(col+2,state,nex|(1<<col)); 46 dfs(col+1,state,nex); 47 } 48 49 void solve() 50 { 51 for(int state=0;state<(1<<m);state++) 52 { 53 dfs(0,state,0); 54 } 55 memset(dp,0,sizeof(dp)); 56 for(int i=0;i<transfer[0].size();i++) 57 { 58 int state=transfer[0][i]; 59 if(!(field[0]&state)) dp[state][0]=1; 60 } 61 for(int i=0;i<n;i++) 62 { 63 for(int state=0;state<(1<<m);state++) 64 { 65 if(dp[state][i]!=0 && !(field[i]&state)) 66 { 67 for(int j=0;j<transfer[state].size();j++) 68 { 69 int nex=transfer[state][j]; 70 if(!(field[i+1]&nex)) 71 { 72 dp[nex][i+1]+=dp[state][i]; 73 dp[nex][i+1]%=MOD; 74 } 75 } 76 } 77 } 78 } 79 } 80 81 void print() 82 { 83 cout<<dp[0][n]<<endl; 84 } 85 86 int main() 87 { 88 read(); 89 solve(); 90 print(); 91 }