题意:在n*m(1<=n,m<=12)的矩阵上种植玉米,任意共边的方格不能同时种,并且有些特定方格也不能种。问能有多少种种植的方案;
解法;很经典的状压模型。先将每一行的合法状态求出来,12的时候最多377个合法状态。然后进行与行之间的状态转移。最坏复杂度12*(377^2)
代码:
/**************************************************** * author:xiefubao *******************************************************/ #pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <vector> #include <algorithm> #include <cmath> #include <map> #include <set> #include <stack> #include <string.h> using namespace std; #define eps 1e-8 typedef long long LL; int inf= 100000000; int rem[15][15]; int legal[10000]; int p=0; int n,m; int num[20]; bool OK(int k) { return !(k&(k<<1)); } int ans[20][10000]; int main() { scanf("%d%d",&n,&m); for(int i=0;i<n;i++) for(int j=0;j<m;j++) { scanf("%d",rem[i]+j); if(rem[i][j]==0) num[i]+=1<<j; } for(int i=0;i<(1<<m);i++) { if(OK(i)) legal[p++]=i; } cout<<p<<endl; for(int i=0;i<p;i++) { if((legal[i]&num[0])==0) ans[0][i]=1; } for(int i=1;i<n;i++) { for(int j=0;j<p;j++) { for(int k=0;k<p;k++) { if(((legal[j]&legal[k])==0)&&(legal[k]&num[i])==0) ans[i][k]=(ans[i][k]+ans[i-1][j])%inf; } } } int out=0; for(int i=0;i<p;i++) { out=(out+ans[n-1][i])%inf; } cout<<out<<endl; return 0; }
poj3254(Corn Fields)状压dp
时间: 2024-10-05 03:23:23