链接:http://poj.org/problem?id=3254
题意:一块M*N的田地。每小块地大小是1*1,能够种植物的标记为1。不能够种植物的标记为0。而且相邻的两块地不能够同一时候种植物。
问题是有多少种不同的种植方案(全部地都不种也是一种种植方案)
思路:这是第一道状压DP题,从第一行更新到最后一行。每一行用一个N位的二进制数来表示该行的状态1表示该位置种了植物,0表示该位置没种植物。由于每块地仅仅对相邻的土地是否能种植有所影响,所以每一行的状态能够用前一行的状态递推得到。
资料:http://www.doc88.com/p-771373748581.html
代码:
#include<iostream> #include<set> #include<map> #include<queue> #include<cstring> #include<string> #include<algorithm> #include<cstdio> #define MOD 100000000 using namespace std; int dp[15][40000]; bool judge(int x) { if((x&(x<<1))==0) return 1; return 0; }//函数用来推断i状态是否有相邻的土地种植了植物,假设没有,返回1 int main() { int row,col,x; int field[15]; memset(field,0,sizeof(field)); memset(dp,0,sizeof(dp)); scanf("%d%d",&row,&col); for(int i=0; i<row; i++) { for(int j=0; j<col; j++) { scanf("%d",&x); field[i]*=2; field[i]+=x; } //cout<<field[i]<<endl; } for(int i=0; i<(1<<col); i++) { if((field[0]&i)==i&&judge(i)) dp[0][i]=1; } for(int i=1; i<row; i++) { for(int j=0; j<(1<<col); j++) { if((field[i]&j)==j&&judge(j)) { for(int k=0; k<(1<<col); k++) { if((k&j)==0&&judge(k)) { dp[i][j]+=dp[i-1][k]; dp[i][j]%=MOD; } } } } } int ans=0; for(int i=0; i<(1<<col); i++) { ans+=dp[row-1][i]; ans%=MOD; } printf("%d ",ans); return 0; }