链接: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\n",ans); return 0; }
时间: 2024-10-13 12:02:55