题目链接:https://vjudge.net/contest/224636#problem/G

转载于:https://blog.csdn.net/harrypoirot/article/details/23163485

题目大意:

农夫有一块地,被划分为m行n列大小相等的格子,其中一些格子是可以放牧的(用1标记),农夫可以在这些格子里放牛,其他格子则不能放牛(用0标记),并且要求不可以使相邻格子都有牛。现在输入数据给出这块地的大小及可否放牧的情况,求该农夫有多少种放牧方案可以选择(注意:任何格子都不放也是一种选择,不要忘记考虑!

解题分析就看上面那篇博客,我也是照着上面学的。

#include <cstdio>
#include <cstring>
using namespace std; #define mod 100000000
int M, N, top = ;
//top表示每行最多的状态数 int state[];
//state存放每行所有的可行状态(即没有相邻的状态) int dp[][];
//dp[i][j]:对于前i行数据,第i行有前j种可能状态时的解
int cur[];
//cur[i]表示的是第i行整行的情况 inline bool ok(int x) { //判断状态x是否可行
if (x&x << ) return false;//若存在相邻两个格子都为1,则该状态不可行
return true;
} void init() { //遍历所有可能的状态
top = ;
int total = << N; //遍历状态的上界
for (int i = ; i < total; ++i) { //总共有total种状态需要讨论
if (ok(i))state[++top] = i; //state[]为一行中所有可行的状态
}
}
//原理就是,如果你在不能够放1的位置放了1,那么这个方案肯定不可行
inline bool fit(int x, int k) { //判断状态x 与第k行的实际状态的逆是否有‘重合’ //判断理论上每一行能符合的情况是否与某一特定的行符合,因为每一行规定了能放1的位置
if (x&cur[k])return false; //若有重合,(即x不符合要求)
return true; //若没有,则可行
} int main() {
while (scanf("%d%d", &M, &N) != EOF) {
init();
memset(dp, , sizeof(dp));
for (int i = ; i <= M; ++i) {
cur[i] = ;
int num;
for (int j = ; j <= N; ++j) { //输入时就要按位来存储,cur[i]表示的是第i行整行的情况,每次改变该数字的二进制表示的一位
scanf("%d", &num); //表示第i行第j列的情况(0或1)
if (num == ) //若该格为0
cur[i] += ( << (N - j)); //则将该位置为1(注意要以相反方式存储,即1表示不可放牧
} //cur[]数组,利用状态压缩,用一维数组,表示了二维的数据
}
for (int i = ; i <= top; i++) {
if (fit(state[i], )) { //判断所有可能状态与第一行的实际状态的逆是否有重合
dp[][i] = ; //若第1行的状态与第i种可行状态吻合,则dp[1][i]记为1
}
} //先算出第一行的情况,初始化dp[1][]的所有情况,方便下面dp的递推, //前面的都是准备工作,都是为了下面的这个状态转移方程做准备 for (int i = ; i <= M; ++i) { //i索引第2行到第M行
for (int k = ; k <= top; ++k) { //该循环针对所有可能的状态,找出一组与第i行相符的state[k]
if (!fit(state[k], i))continue; //判断是否符合第i行实际情况
for (int j = ; j <= top; ++j) { //找到state[k]后,再找一组与第i-1行符合,且与第i行(state[])不冲突的状态state[j]
if (!fit(state[j], i - ))continue; //判断是否符合第i-1行实际情况 //找出上一行的所有可行状态
if (state[k] & state[j])continue; //判断是否与第i行冲突 //判断第i行的状态是否与上一行冲突
dp[i][k] = (dp[i][k] + dp[i - ][j]) % mod; //若以上皆可通过,则将'j'累加到‘k'上
} //这里就相当于dp[i][k]+=dp[i-1][j],只不过因为要取模运算,所以写成这样
} //状态转移方程的根据为,dp[i][k]表示第i行采用方案k时,前i总共有多少种可行的情况
}
int ans = ;
for (int i = ; i <= top; ++i) { //累加最后一行所有可能状态的值,即得最终结果!!!
ans = (ans + dp[M][i]) % mod;
}
printf("%d\n", ans);
}
}

2018-07-26

Poj - 3254 Corn Fields (状压DP)(入门)的更多相关文章

  1. poj 3254 Corn Fields 状压dp入门

    题目链接 题意 在\(M\times N\)的\(0,1\)格子上放东西,只有标记为\(1\)的格子可以放东西,且相邻的格子不能同时放东西.问有多少种放法. 思路 参考:swallowblank. \ ...

  2. POJ 3254 Corn Fields (状压dp)

    题目链接:http://poj.org/problem?id=3254 给你n*m的菜地,其中1是可以种菜的,而菜与菜之间不能相邻.问有多少种情况. 状压dp入门题,将可以种菜的状态用一个数的二进制表 ...

  3. POJ 3254 - Corn Fields - [状压DP水题]

    题目链接:http://poj.org/problem?id=3254 Time Limit: 2000MS Memory Limit: 65536K Description Farmer John ...

  4. [ An Ac a Day ^_^ ] POJ 3254 Corn Fields 状压dp

    题意: 有一块n*m的土地 0代表不肥沃不可以放牛 1代表肥沃可以放牛 且相邻的草地不能同时放牛 问最多有多少种放牛的方法并对1e8取模 思路: 典型的状压dp 能状态压缩 能状态转移 能状态压缩的题 ...

  5. POJ 1684 Corn Fields(状压dp)

    描述 Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ ...

  6. POJ 3254 Corn Fields (状压入门)

    Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M≤ 12; 1 ≤ N ≤ 12) ...

  7. poj - 3254 Corn Fields (状态压缩dp入门)

    http://poj.org/problem?id=3254 参考:http://blog.csdn.net/accry/article/details/6607703 农夫想在m*n的土地上种玉米, ...

  8. P1879 [USACO06NOV]玉米田Corn Fields (状压dp入门)

    题目链接: https://www.luogu.org/problemnew/show/P1879 具体思路: 我们可以先把所有合法的情况枚举出来,然后对第一行判断有多少种情况满足,然后对于剩下的行数 ...

  9. 【POJ3254】Corn Fields 状压DP第一次

    !!!!!!! 第一次学状压DP,其实就是运用位运算来实现一些比较,挺神奇的.. 为什么要发“!!!”因为!x&y和!(x&y)..感受一下.. #include <iostre ...

随机推荐

  1. vue axios全攻略

    不再继续维护vue-resource,并推荐大家使用 axios 开始,axios 被越来越多的人所了解.本来想在网上找找详细攻略,突然发现,axios 的官方文档本身就非常详细!!有这个还要什么自行 ...

  2. python Twisted安装报错

    系统 mac pro 错误信息: IOError: [Errno 63] File name too long: '/var/folders/72/byjy11cs0dj_z3rjtxnj_nn000 ...

  3. springboot项目发布到独立的tomcat中运行&打成jar包运行

    springboot的打包方式依赖于插件:(下面插件打出的包与普通的包目录结构有区别) <plugin> <groupId>org.springframework.boot&l ...

  4. redis实现消息队列&发布/订阅模式使用

    在项目中用到了redis作为缓存,再学习了ActiveMq之后想着用redis实现简单的消息队列,下面做记录.   Redis的列表类型键可以用来实现队列,并且支持阻塞式读取,可以很容易的实现一个高性 ...

  5. OpenCV:Debug和Release模式 && 静态和动态编译

    1.Release和Debug的区别 Release版称为发行版,Debug版称为调试版. Debug中可以单步执行.跟踪等功能,但生成的可执行文件比较大,代码运行速度较慢.Release版运行速度较 ...

  6. linux 高级字符设备驱动 ioctl操作介绍 例程分析实现【转】

    转自:http://my.oschina.net/u/274829/blog/285014 1,ioctl介绍 ioctl控制设备读写数据以及关闭等. 用户空间函数原型:int ioctl(int f ...

  7. class_create(),device_create自动创建设备文件结点【转】

    本文参考来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhenwenxian/archive/2010/03/28/5424434.aspx 本文转自:http://ww ...

  8. Nginx软件优化【转】

    转自 Nginx软件优化 - 惨绿少年 - 博客园 Nginx软件优化 - 惨绿少年 - 博客园 https://www.cnblogs.com/clsn/p/8484559.html 1.1 Ngi ...

  9. SharePoint 2013 Workflow Manager 1.0 卸载

    一:环境 Window server 2012 r2 Standard SharePoint Server 2013 with sp1 二:开始菜单---Workflow Manager 配置---退 ...

  10. Windows下虚拟机安装Mac OS X —– VM12安装Mac OS X 10.11

    ____________________________________________________________________________________________________ ...