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;
}
浙公网安备 33010602011771号