poj3254

#include <iostream>
using namespace std;

#define mod 100000000
#define maxn (1<<12)+1
bool map[14][14];
int dp[2][maxn];

int n,m;
int son[maxn];
void dfs(int x,int k,int y,int& top,bool can[])
{
     if(k>m)
     {
            son[top++]=y;
            return;
     }
     else
     {
         if((x&(1<<(k-1))))
         {
                           dfs(x,k+1,y,top,can);
         }
         else
         {
               if(can[m+1-k]&&(k==1||(!(y&(1<<(k-2))))))dfs(x,k+1,y+(1<<(k-1)),top,can);
               dfs(x,k+1,y,top,can);
         }
     }
     return;
}
int main()
{
    int top;
    for(;scanf("%d%d",&n,&m)==2;)
    {
         memset(map,false,sizeof(map));
         memset(dp,0,sizeof(dp));
         memset(son,-1,sizeof(son));
         for(int i=1;i<n+1;i++)
         for(int j=1;j<m+1;j++)
         scanf("%d",&map[i][j]);
    
         for(int i=0;i<n;i++)
         {
                 if(i==0)
                 {
                        top=0;
                        dfs(0,1,0,top,map[1]);
                        for(int j=0;j<top;j++)
                        {
                                dp[1][son[j]]++;
                                while(dp[1][son[j]]>=mod)dp[1][son[j]]-=mod;
                        }
                 }
                 else
                 {
                     memcpy(dp[0],dp[1],sizeof(dp[0]));
                     memset(dp[1],0,sizeof(dp[1]));
                     for(int j=0;j<(1<<(m));j++)
                     {
                              top=0;
                              dfs(j,1,0,top,map[i+1]);
                              for(int k=0;k<top;k++)
                              {
                                      dp[1][son[k]]=dp[0][j]+ dp[1][son[k]];
                                      while(dp[1][son[k]]>=mod)dp[1][son[k]]-=mod;
                              }
                     }
                 }
         }
         int sum=0;
         for(int j=0;j<(1<<(m));j++)
         {
                 sum+=dp[1][j];
                 while(sum>=mod)sum-=mod;
         }
         printf("%d\n",sum);
         
         
    }
return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值