http://poj.org/problem?id=3254
poj 你又亮了 我感觉时间复杂度这么高的程序 你居然让我 0ms 过了
无语了
给你矩阵 有的地方可以种植 有的地方不可以
种植位置不可相邻 问最多有多少种 种法
最多宽度为12 把其中一维 的种不种 转化为 对应位 的二进制1 或0
让后更新就可以了
代码及其注释:
#include<iostream> #include<stdio.h> #include<string.h> #include<queue> #include<cmath> #include<stack> #include<algorithm> using namespace std; const int mod=100000000; const int N=15; int fertile[N][N];//土地是否肥沃 int sum[N][1<<12];//第几 行 把列的种类用二进制对应起来 bool Can(int i,int k,int m)//第i行 为k 是能不能种 { int pre=0; for(int j=1;j<=m&&k;++j,k=k/2) { if(fertile[i][j]==0&&k%2==1)//种的地方土地必须肥沃 return false; if(k%2==1&&pre==1)//不能有相邻 1 return false; pre=k%2; } return true; } int main() { int n,m; while(scanf("%d %d",&n,&m)!=EOF) { memset(fertile,0,sizeof(fertile)); for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j) { scanf("%d",&fertile[i][j]); } } memset(sum,0,sizeof(sum)); int ans=0; int M=1<<m; for(int i=1;i<=n;++i) { for(int j=0;j<M;++j) { if(Can(i,j,m)) { if(i==1) sum[i][j]=1; else { for(int l=0;l<M;++l) { if((j&l)==0)//可以累加 { sum[i][j]=(sum[i][j]+sum[i-1][l])%mod; } } } if(i==n) { ans=(ans+sum[i][j])%mod; } } } } printf("%d\n",ans); } return 0; }