您的位置:首页 > 其它

POJ 3254 Corn Fields (状态压缩DP)

2013-06-04 22:57 363 查看
看了好几回状态压缩dp了,也看 了不少博客,今天经过 贺贺的讲解对 位运算有了认识,参考了一下贺贺 的博客,终于做了第一道状态压缩dp题,还要努力( ⊙ o ⊙ )啊……

状态压缩dp的一个很好的博客:http://blog.csdn.net/accry/article/details/6607703

题目:http://poj.org/problem?id=3254

题意:一个n*m的矩阵,每个格子是0或者1,1表示土壤肥沃可以种植草地,0则不可以。在种草地的格子可以放牛,但边相邻的两个格子不允许同时放牛,问总共有多少种放牛的方法?(不放牛也算一种情况)

AC代码如下

//注意位运算符优先级很低
#include<stdio.h>
#include<string.h>
#define mo 100000000
int corn[15],dp[15][1<<13];

int ok(int x,int y)
{
if((x&y)!=x)  return 0;//判断牛的状态和草地是否匹配
if(x&(x<<1))  return 0;//判断左右是否相邻
return 1;
};

int main()
{
int n,m,i,j,k,t,ans;
while(~scanf("%d%d",&n,&m))
{
memset(corn,0,sizeof(corn));
for(i=1; i<=n; i++)
{
for(j=0; j<m; j++)
{
scanf("%d",&t);
corn[i]=(corn[i]<<1)+t;//corn表示草地的状态情况
}
}

memset(dp,0,sizeof(dp));

for(j=0; j<(1<<m); j++)//初始第一行草地
if(ok(j,corn[1]))
dp[1][j]=1;

for(i=2; i<=n; i++)
for(j=0; j<(1<<m); j++)
{
if(ok(j,corn[i]))
for(k=0; k<(1<<m); k++)
if((j&k)==0)//判断是否与上一行相邻
dp[i][j]=(dp[i][j]+dp[i-1][k])%mo;//状态方程,并按题意取余
}

ans=0;
for(j=0; j<(1<<m); j++)
ans=(ans+dp
[j])%mo;//将所有情况加起来

printf("%d\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: