题目链接: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. [JSOI2008]球形空间产生器 (高斯消元)

    [JSOI2008]球形空间产生器 \(solution:\) 非常明显的一道高斯消元.给了你n+1个球上的位置,我们知道球上任何一点到球心的距离是相等,所以我们 可以利用这一个性质.我们用n+1个球 ...

  2. [转]Linux/Windows下脚本对拍程序

    [新]简单写法 (转载自:https://blog.csdn.net/ylsoi/article/details/79824655) 要求:文件输入输出,且输入输出文件需要对应 Linux: #inc ...

  3. python作业简单FTP(第七周)

    作业需求: 1. 用户登陆 2. 上传/下载文件 3. 不同用户家目录不同 4. 查看当前目录下文件 5. 充分使用面向对象知识 思路分析: 1.用户登陆保存文件对比用户名密码. 2.上传用json序 ...

  4. SpringBoot集成Spring Security(授权与认证)

    ⒈添加starter依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifact ...

  5. 扫AR

  6. python通过操作windows系统注册表方式修改环境变量

    #coding=utf8 import os import sys from subprocess import check_call if sys.hexversion > 0x0300000 ...

  7. Project Euler Problem9

    Special Pythagorean triplet Problem 9 A Pythagorean triplet is a set of three natural numbers, a  b  ...

  8. Android开源动画库nineoldandroids

    项目官网地址:http://nineoldandroids.com/ 使用这个库的原因是android3.0之后出了新的animation API,但是android3.0以下的不支持 这个库完成了这 ...

  9. Ex 6_14 布料剪裁问题_第八次作业

    子问题定义: 定义p[i][j]为布料宽为i,高为j的最优产出,每次剪下一块布料,剩余布料最多形成三块矩阵面料.每次剪裁会有两种情况,水平切割布料,其次是将布料旋转90度后在切割布料. 递归关系: 初 ...

  10. 基于react/vue的移动端终极适配方案vw单位(更新css-modules配置)

    传送门:  https://segmentfault.com/a/1190000014185590