poj 3254

来源:互联网 发布:mac toast and butter 编辑:程序博客网 时间:2024/06/10 07:13

题意:Farmer John 放牧cow,有些草地上的草是不能吃的,用0表示,然后规定两头牛不能相邻放牧。问你有多少种放牧方法。

这题的状态很好设定dp[i][j]:表示i行的第j中状态可以放牧的总数,显然要先对状态先预处理,然后dp只要看看能不能从上1层的状态转移过来,这里注意位运算的用法,然后就很简单了。

神奇的1Y。

Run IDUserProblemResultMemoryTimeLanguageCode LengthSubmit Time91985222010307204253254Accepted224K47MSC++1063B2011-08-20 11:38:21

#include<cstdio>#include<cstring>#include<string>#include<iostream>#include<cmath>#include<algorithm>using namespace std;int sta[1<<16],a[16],dp[16][10000],n,m,num=0;void init(){int sum=1<<m;for(int i=0;i<sum;i++)if(i&(i<<1))continue;elsesta[num++]=i;}bool fit(int x,int y){if(x&y)return 0;return 1;}void DP(){for(int i=0;i<num;i++)if(fit(sta[i],a[1]))  dp[1][i]=1;for(int i=2;i<=n;i++)for(int j=0;j<num;j++)if(!fit(sta[j],a[i]))continue;else{for(int k=0;k<num;k++){if(!fit(a[i-1],sta[k]))continue;if(!fit(sta[k],sta[j]))continue;dp[i][j]=(dp[i][j]+dp[i-1][k])%100000000;}}int ans=0;for(int i=0;i<num;i++)ans=(ans+dp[n][i])%100000000;printf("%d\n",ans);}int main(){int tem;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){scanf("%d",&tem);if(tem==0)a[i]+=1<<(m-j);}init();DP();return 0;}