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;
}

  

posted on 2012-07-20 16:08  夜->  阅读(197)  评论(0编辑  收藏  举报