poj 3254 Corn Fields(状态压缩dp)
2017-09-03 20:11
483 查看
状态压缩dp入门。
参考:http://www.cnblogs.com/BlackStorm/p/4706243.html
我的理解都在注释里。
参考: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; }
相关文章推荐
- POJ 3254 Corn Fields 状态压缩DP
- POJ 3254 Corn Fields 状态压缩DP
- POJ 3254 Corn Fields(状态压缩DP)
- poj 3254 Corn Fields (状态压缩DP)
- poj 3254 Corn Fields 状态压缩dp
- poj 3254 Corn Fields(状态压缩DP)
- poj 3254 Corn Fields【状态压缩dp-入门】
- POJ3254——Corn Fields(状态压缩DP)
- poj 3254 Corn Fields(状态压缩dp)
- poj 3254 Corn Fields(状态压缩dp)
- POJ 3254 Corn Fields——状态压缩dp
- POJ 3254 Corn Fields(状态压缩DP)
- POJ 3254 Corn Fields(状态压缩dp)
- POJ 3254 Corn Fields(状态压缩dp)
- POJ 3254 Corn Fields(状态压缩DP)
- POJ 3254 Corn Fields(DP + 状态压缩)
- 状态压缩dp入门 第一题 POJ 3254 Corn Fields
- POJ 3254 Corn Fields(状态压缩DP)
- POJ 3254 Corn Fields (状态压缩DP)
- poj 3254 Corn Fields_状态压缩dp