【POJ3254】Corn Fields

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<ctime>
#include<algorithm>
#define RG register
#define maxn 1<<14
#define MOD 100000000
using namespace std;
int n,m,ans=0;
int dp[13][maxn];
int line[maxn];
inline int read()
{
	int s=0,k=1;
	char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
	if(ch=='-') k=-1,ch=getchar();
	while(ch>='0'&&ch<='9') s=s*10+(ch-'0'),ch=getchar();
	return s*k;
}
inline int check1(int x)
{
	if(x&x<<1) return false;
	return true;
}
inline int check2(int x,int y)
{
	if(x&line[y]) return false;
	return true;
}
int main()
{	
   while(scanf("%d%d",&n,&m)!=EOF)
   {
   	ans=0;
	int minn=1<<m;
	memset(dp,0,sizeof(dp));
	memset(line,0,sizeof(line));
	for(int i=1;i<=n;i++)
	 for(int j=1;j<=m;j++)
	  {
	  	int num=read();
	  	if(num==0) line[i]+=1<<(m-j);
	  }
	for(int i=0;i<minn;i++) if(check1(i)&&check2(i,1)) dp[1][i]=1;  
	for(int i=2;i<=n;i++)
	 for(int k=0;k<minn;k++)//枚举当前行状态 
	 {
	 	if(check1(k)&&check2(k,i))//判断这个状态合法以及这个状态与当前行要求状态合法 
	 	{
	 		for(int j=0;j<minn;j++)//枚举前一行状态 
	 		{
			 if(check1(j)&&check2(j,i-1))//判断这个状态合法以及这个状态与当前行要求状态合法
			 {
				if((j&k)==0)			 
			 	 dp[i][k]=(dp[i][k]+dp[i-1][j])%MOD; 
			 }
			} 
		}
	}
	for(int i=0;i<minn;i++) ans=(ans+dp[n][i])%MOD;
	printf("%d\n",ans%MOD);
	}
	return 0;   
}

这道题其实思路很容易, 我们可以轻松地推出状态转移方程为:         F[i][k]=F[i-1][∑1--1<<M]     再就只需要利用位运算,进行状态判断合法就可以了。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值