您的位置:首页 > 其它

poj 3254 Corn Fields(状态压缩dp)

2017-09-03 20:11 483 查看
状态压缩dp入门。

参考:http://www.cnblogs.com/BlackStorm/p/4706243.html

我的理解都在注释里。

#include <stdio.h>
const int mod = 1e8;
int row[13],rec[377],dp[13][377];

int main()
{
int x=1<<12, k=0;
//先不考虑哪些土地能种植,哪些土地不能种植
//枚举出一行的所有合法状态,即两头牛不相邻
for(int i = 0; i < x; ++i)
{
if(!(i&(i<<1)))
rec[k++]=i;
}
rec[k]=x;

int M,N,t;
scanf("%d%d",&M,&N);
//输入土地的状态,即哪些能种植,哪些不能种植
//把状态翻转过来,0表示可种植,1表示不可种植
//这样只有当行种植状态和行状态相与为0,这个种植状态才在该行有效,
//因为如果种在了不肥沃的格子上,相位与会保留位1,结果不为0。
for(int i = 0; i < M; ++i)
for(int j = 0; j < N; ++j)
{
scanf("%d",&t);
row[i] = (row[i]<<1)|!t;
}
x=1<<N;
//处理第一行
for(int i = 0; rec[i]<x; ++i)
{
if(!(row[0]&rec[i]))
dp[0][i] = 1;
}
//枚举1-M行的状态
for(int r = 1; r<M; ++r)
{
//枚举当前行上一行的所有可能状态
for(int i = 0; rec[i]<x; ++i)
{
//判断这个状态能否合法种植在上一行
if(!(row[r-1]&rec[i]))
{
//再枚举当前行所有可能状态
for(int j = 0; rec[j]<x; ++j)
//判断在当前行能否合法种植
if(!(row[r]&rec[j]))
//载判断与上一行是否冲突
if(!(rec[i]&rec[j]))
dp[r][j] = (dp[r][j]+dp[r-1][i])%mod;
}
}
}
int r = M-1;
for(int i = 1; rec[i]<x; ++i)
dp[r][0] = (dp[r][0]+dp[r][i])%mod;
printf("%d\n",dp[r][0]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: