您的位置:首页 > 其它

POJ 3254 Corn Fields 状压DP

2014-07-19 20:40 288 查看
链接:http://poj.org/problem?id=3254

题意:一块M*N的田地,每小块地大小是1*1,可以种植物的标记为1,不可以种植物的标记为0,并且相邻的两块地不可以同时种植物。问题是有多少种不同的种植方案(所有地都不种也是一种种植方案)

思路:这是第一道状压DP题,从第一行更新到最后一行,每一行用一个N位的二进制数来表示该行的状态1表示该位置种了植物,0表示该位置没种植物。因为每块地只对相邻的土地能否种植有所影响,所以每一行的状态可以用前一行的状态递推得到。

资料:http://www.doc88.com/p-771373748581.html

代码:

#include<iostream>
#include<set>
#include<map>
#include<queue>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdio>
#define MOD 100000000
using namespace std;
int dp[15][40000];
bool judge(int x)
{
if((x&(x<<1))==0)
return 1;
return 0;
}//函数用来判断i状态是否有相邻的土地种植了植物,如果没有,返回1
int main()
{
int row,col,x;
int field[15];
memset(field,0,sizeof(field));
memset(dp,0,sizeof(dp));
scanf("%d%d",&row,&col);
for(int i=0; i<row; i++)
{
for(int j=0; j<col; j++)
{
scanf("%d",&x);
field[i]*=2;
field[i]+=x;
}
//cout<<field[i]<<endl;
}
for(int i=0; i<(1<<col); i++)
{
if((field[0]&i)==i&&judge(i))
dp[0][i]=1;
}
for(int i=1; i<row; i++)
{
for(int j=0; j<(1<<col); j++)
{
if((field[i]&j)==j&&judge(j))
{
for(int k=0; k<(1<<col); k++)
{
if((k&j)==0&&judge(k))
{
dp[i][j]+=dp[i-1][k];
dp[i][j]%=MOD;
}

}
}
}
}
int ans=0;
for(int i=0; i<(1<<col); i++)
{
ans+=dp[row-1][i];
ans%=MOD;
}
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  DP