题目链接: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. A - 最大子矩阵 HYSBZ - 1084 (DP)

    题目链接:https://cn.vjudge.net/contest/281963#problem/A 题目大意:中文题目 具体思路:观察到m<=2,所以我们可以对两种情况进行单独讨论,当m== ...

  2. python - 用类写装饰器

    这里用到了__call__的class内置参数 #类装饰器: class zsq(): #本质是定义一个参数,让装饰的主题传递至__call__方法内部 def __init__(self,obj): ...

  3. CentOS7配置网络

    #进入目录 cd /etc/sysconfig/network-scripts/ #编辑ifcfg-XXX vi ifcfg-eno167777 #把onboot=no 改为yes #重启 shutd ...

  4. SRS服务器搭建,ffmpeg 本地推流,srs从本地拉流

    参考: https://github.com/ossrs/srs/wiki/v2_CN_SampleFFMPEG git clone https://github.com/ossrs/srs cd s ...

  5. argv[1] 路径问题

    在看<学习opencv>一书时遇到一个小问题:函数只是通过argv传递参数来读取图片并显示,但是却一直弹出画布,没有图像. 如下:test.c # include<stdio.h&g ...

  6. Python 优雅获取本机 IP 方法【转】

    转自:https://www.cnblogs.com/lfxiao/p/9672975.html 见过很多获取服务器本地IP的代码,个人觉得都不是很好,例如以下这些 不推荐:靠猜测去获取本地IP方法 ...

  7. Python3学习笔记19-继承和多态

    在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承, 新的class称为子类(Subclass),而被继承的class称为基类.父类或超类(Base class.Sup ...

  8. 【转】深入浅出JMS(二)--ActiveMQ简单介绍以及安装

    现实的企业中,对于消息通信的应用一直都非常的火热,而且在J2EE的企业应用中扮演着特殊的角色,所以对于它研究是非常有必要的. 这篇博文介绍一款开源的JMS具体实现——ActiveMQ.ActiveMQ ...

  9. (网络编程)socketserver模块服务端实现并发

    基于tcp的套接字(实现并发),关键就是两个循环,一个链接循环,一个通信循环 基于udp的套接字(不是正真意义上的并发,实现真并发) socketserver模块中分两大类:server类(解决链接问 ...

  10. Linux中 Lua 访问Sql Server的配置方法

    一.背景说明: 通过lua脚本实现对SQL Server数据库的操作. 二.具体设定: 安装流程图:如果是使用Lua连接SQL Server,从上到下则需要安装lua -> luaSQL-ODB ...