Poj - 3254 Corn Fields (状压DP)(入门)
题目链接: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)(入门)的更多相关文章
- poj 3254 Corn Fields 状压dp入门
题目链接 题意 在\(M\times N\)的\(0,1\)格子上放东西,只有标记为\(1\)的格子可以放东西,且相邻的格子不能同时放东西.问有多少种放法. 思路 参考:swallowblank. \ ...
- POJ 3254 Corn Fields (状压dp)
题目链接:http://poj.org/problem?id=3254 给你n*m的菜地,其中1是可以种菜的,而菜与菜之间不能相邻.问有多少种情况. 状压dp入门题,将可以种菜的状态用一个数的二进制表 ...
- POJ 3254 - Corn Fields - [状压DP水题]
题目链接:http://poj.org/problem?id=3254 Time Limit: 2000MS Memory Limit: 65536K Description Farmer John ...
- [ An Ac a Day ^_^ ] POJ 3254 Corn Fields 状压dp
题意: 有一块n*m的土地 0代表不肥沃不可以放牛 1代表肥沃可以放牛 且相邻的草地不能同时放牛 问最多有多少种放牛的方法并对1e8取模 思路: 典型的状压dp 能状态压缩 能状态转移 能状态压缩的题 ...
- POJ 1684 Corn Fields(状压dp)
描述 Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ ...
- POJ 3254 Corn Fields (状压入门)
Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M≤ 12; 1 ≤ N ≤ 12) ...
- poj - 3254 Corn Fields (状态压缩dp入门)
http://poj.org/problem?id=3254 参考:http://blog.csdn.net/accry/article/details/6607703 农夫想在m*n的土地上种玉米, ...
- P1879 [USACO06NOV]玉米田Corn Fields (状压dp入门)
题目链接: https://www.luogu.org/problemnew/show/P1879 具体思路: 我们可以先把所有合法的情况枚举出来,然后对第一行判断有多少种情况满足,然后对于剩下的行数 ...
- 【POJ3254】Corn Fields 状压DP第一次
!!!!!!! 第一次学状压DP,其实就是运用位运算来实现一些比较,挺神奇的.. 为什么要发“!!!”因为!x&y和!(x&y)..感受一下.. #include <iostre ...
随机推荐
- python的特殊方法介绍
__repr__.__str__ __len__.__getitem__.__setitem__.__delitem__.__contains__ __iter__.__reversed__.__ne ...
- 你真的懂 ajax 吗?
前言 总括: 本文讲解了ajax的历史,工作原理以及优缺点,对XMLHttpRequest对象进行了详细的讲解,并使用原生js实现了一个ajax对象以方便日常开始使用. damonare的ajax库: ...
- jquery选择器最后一个,倒数第二个元素
<div> <p>1</p> <p>2</p> <p>3</p> <p>4</p> < ...
- ActiveMQ安装与入门程序 & JMS的消息结构
1.Activemq安装 直接到官网下载:记住apache的官网是域名反过来,比如我们找activemq就是activemq.apache.org. 最新版本要求最低的JDK是8,所以最好在电脑装多个 ...
- Bootstrap模态框(一个页面显示多个)的使用
在一个页面显示多个模态框时要讲每个模态框用div包裹起来,否咋会产生格式错误. <html> <head> <meta charset="utf-8" ...
- yield函数的理解
1.https://blog.csdn.net/qq_33472765/article/details/80839417
- ROS中的CMakeLists.txt
在ROS的编程过程中,如果CMakeLists.txt如果写不好,编译就很难成功.如果看不懂CMakeLists.txt那么很多错误你也不知道时什么回事.所以深入了解它是很有必要的.现在我们就来看看它 ...
- ROS学习笔记(一) # ROS参数服务器
参考 roscpp/Overview/Parameter Server 0. 概述 ROS参数服务器能够保存 string, int, float, double, bool, list, dicti ...
- 【转】Python中的运算符
[转]Python中的运算符 说完常用的数据类型,再来说下运算符.运算符用于将各种类型的数据进行运算,让静态的数据跑起来. 编程语言中的运算大致分为以下几个大类: 算术运算, 用于加减乘除等数学运算 ...
- 【Shell】获取当前路径
bathpath=$(cd dirname $0 ; pwd)