Corn Fields
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 6460   Accepted: 3436

Description

Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parcels. He wants to grow some yummy corn for the cows on a number of squares. Regrettably, some of the squares are infertile and can't be planted. Canny FJ knows that the cows dislike eating close to each other, so when choosing which squares to plant, he avoids choosing squares that are adjacent; no two chosen squares share an edge. He has not yet made the final choice as to which squares to plant.

Being a very open-minded man, Farmer John wants to consider all possible options for how to choose the squares for planting. He is so open-minded that he considers choosing no squares as a valid option! Please help Farmer John determine the number of ways he can choose the squares to plant.

Input

Line 1: Two space-separated integers: M and N 
Lines 2..M+1: Line i+1 describes row i of the pasture with N space-separated integers indicating whether a square is fertile (1 for fertile, 0 for infertile)

Output

Line 1: One integer: the number of ways that FJ can choose the squares modulo 100,000,000.

Sample Input

2 3
1 1 1
0 1 0

Sample Output

9

Hint

Number the squares as follows:

1 2 34  

There are four ways to plant only on one squares (1, 2, 3, or 4), three ways to plant on two squares (13, 14, or 34), 1 way to plant on three squares (134), and one way to plant on no squares. 4+3+1+1=9.

题意:农夫FJ有一块n行m列的矩形土地, 有的土地是肥沃的,可以在这些土地上放牛(用1表示),有的土地不能放牛(用0表示),而且相邻的可以放牛的格子不能同时有牛,问FJ一共有多少种放牛的方案(一头牛都不放也是一种方案)。

分析:以样例为例,我们可以一行一行的考虑。假如对于每一行,用1表示放牛,0表示不放牛,

第一行的状态为:000001010011(舍弃) 100101110(舍弃)111(舍弃)

符合题意的状态只有5个,所以第一行有5种方案。

第二行的状态为:000010

但是第二行中的010和第一行中的010冲突,所以如果第二行状态为010时,共有4种方案;状态为000时,有5种方案,所以一共有4+5=9种方案。

分析完我们会发现,对于每一行,都可以一个01串来表示这一行的状态,而这个状态可以用一个十进制整数来代替,也就是说,把这个状态压缩成了一个十进制整数,所以称为是状态压缩。

本题中,dp[i][j] 就表示第i行状态为j时的方案数。

状态压缩dp中最常见的就是位运算,因为位运算可以很方便的判断当前状态是否合法。例如本题中判断第i行是不是有两块相邻的土地同时都有牛,假设当前状态为X,那么只需要判断X&(X>>1)或者X&(X<<1)的结果是不是0,如果是0,说明没有相邻的,否则就说明有相邻的。

#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
#define mod 100000000
const int N = 1<<12 + 4;
int dp[15][N], Map[15][15];
int n, m;
vector<int> vec[14];
int Pow(int a, int x) //2的X次方
{int s = 1;for(int i = 1; i <= x; i++)s <<= 1;return s;
}
int fun(int x) //求第X行的土地状态,0表示可以放牛,1表示不能放牛
{int s = 0;for(int i = 1; i <= m; i++)s += (!Map[x][i]) * Pow(2, m-i);return s;
}
int main()
{int i, j;while(~scanf("%d%d",&n,&m)){memset(dp, 0, sizeof(dp));memset(vec, 0, sizeof(vec));for(i = 1; i <= n; i++)for(j = 1; j <= m; j++)scanf("%d",&Map[i][j]);vec[0].push_back(0);int k = 1<<m;for(i = 0; i < k; i++)dp[0][i] = 1;for(i = 1; i <= n; i++){int tmp = fun(i); //当前行的状态for(j = 0; j < k; j++){if(j & (j>>1)) continue; //j的二进制表示中有两个相邻的1if(j & tmp) continue; //排除在当前行不符合条件的vec[i].push_back(j);}for(j = 0; j < vec[i].size(); j++) //排除和上一行冲突的{int u = vec[i][j];for(int z = 0; z < vec[i-1].size(); z++){int v = vec[i-1][z];if(u & v) continue;dp[i][u] = (dp[i][u] + dp[i-1][v]) % mod;}}}int ans = 0;for(i = 0; i < k; i++)ans = (ans + dp[n][i]) % mod;printf("%d\n",ans);}return 0;
}

代码二:

/*   dp[i][j] 表示第i行状态为j时的合法状态数量 */#include <cstdio>
#include <cstring>
const int N = 13;
#define mod 100000000
int dp[N][1<<N];
int beg[N];bool checkA(int x) {  //判断本行是否合法return !(x & (x >> 1));
}bool checkB(int a, int b) { //判断和上一行是否冲突return !(a & b);
}int main() {int n, m, t;while(~scanf("%d%d", &n, &m)) {memset(dp, 0, sizeof(dp));memset(beg, 0, sizeof(beg));for(int i = 0; i < n; i++) {for(int j = 0; j < m; j++) {scanf("%d", &t);if(t) beg[i] = beg[i] | (1 << j);}}for(int i = 0; i < (1<<m); i++) //求出第一行的合法状态数目if((beg[0]|i) == beg[0] && checkA(i))dp[0][i] = 1; for(int i = 1; i < n; i++) {for(int j = 0; j < (1<<m); j++) {  //枚举本行状态if(((beg[i]|j) == beg[i]) && checkA(j)) {for(int k = 0; k < (1<<m); k++) { //枚举上一行的状态if(checkB(j, k)) //根据上一行递推出本行dp[i][j] = (dp[i][j] + dp[i-1][k]) % mod;}}}}int ans = 0;for(int i = 0; i < (1<<m); i++)ans = (ans + dp[n-1][i]) % mod;printf("%d\n", ans);}return 0;
}

状态压缩dp入门 第一题 POJ 3254 Corn Fields相关推荐

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

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

  2. poj 3254 Corn Fields 状态压缩dp

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K       Description Farmer John has purchased a ...

  3. POJ 3254 Corn Fields (状态压缩)

    刚开始的思路是  把0-2^x的 所有状态枚举, 然后找符合条件的,   但是 发现 当12*12 时  1的数量x 超过64  这是个庞大的数字, 跟本就没法枚举: 想到用状态压缩,  但是 怎么压 ...

  4. Poj - 3254 Corn Fields (状压DP)(入门)

    题目链接:https://vjudge.net/contest/224636#problem/G 转载于:https://blog.csdn.net/harrypoirot/article/detai ...

  5. POJ - 3254 Corn Fields(状压dp)

    题目链接:点击查看 题目大意:给出一个n*m的地图,有些位置不能放牧,然后放牧的条件是相邻两个格子不允许同时使用,问可行方案有几种 题目分析:因为给出的数据范围很小,并且放牧的状态是放或者不放,很容易 ...

  6. POJ 3254 Corn Fields [DP]

    题意:略. 思路:第一次做状态压缩的dp. 在这里说一下状态压缩的原则.因为每一行只有最多12个格子,每个格子只有1(可放牛)和0(不可放牛)两种状态,这总共是2^12种状态,直接用一个int整型变量 ...

  7. POJ - 3254 - Corn Fields

    线上题目: Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6936   Accepted: 3697 ...

  8. poj 3254 Corn Fields (状态压缩DP)

    题目:http://poj.org/problem?id=3254 思路见代码: #include<iostream> using namespace std;const int MOD= ...

  9. ACWing 327. 玉米田(状态压缩dp入门)

    农夫约翰的土地由M*N个小方格组成,现在他要在土地里种植玉米. 非常遗憾,部分土地是不育的,无法种植. 而且,相邻的土地不能同时种植玉米,也就是说种植玉米的所有方格之间都不会有公共边缘. 现在给定土地 ...

最新文章

  1. 20110125 学习记录:在SQL Server 2005数据库中修改存储过程
  2. Linux grep 命令初步学习
  3. 如何保障消息中间件 100% 消息投递成功?如何保证消息幂等性?
  4. 30万奖金海华AI挑战赛 | 用机器挑战中文阅读理解
  5. 了解 Vue SSR 这一篇足以
  6. EtherCAT伺服驱动器-如何选择硬件开发方案
  7. Unity手游之路lt;七gt;角色控制器
  8. python高手之路第三版_《Python高手之路(第3版)》——1.3 版本编号-阿里云开发者社区...
  9. @requestbody和@requestparam到底什么作用
  10. python导入mongodb_python实现mongodb的备份与导入
  11. 有关正则表达式的一些用法总结
  12. Airflow 中文文档:插件
  13. graphpad7.04多组比较p值_R语言缺失值处理(MICE/Amelia/missForest/Hmisc/mi)
  14. python之路day4_【Python之路Day4】基础篇
  15. (tip_修订0618)bmp 32位转24位
  16. CDC不同模式在ODI体现系列之二 异步模式
  17. matlab 加权残值法,分步迭代加权残值法
  18. JS处理支付宝H5支付
  19. Shader山下(六)镜面高光
  20. 平板做笔记本电脑的副屏教程

热门文章

  1. C++ Boost在Windows和Linux下的编译安装
  2. Python大数据:jieba分词,词频统计
  3. python excel 操作
  4. 15条走红网络的手机摄影技巧
  5. 计算圆形是否和正方形相交 【微软面试100题 第二十三题】
  6. 点滴积累【C#】---操作文件
  7. 如果我要...(开发版)
  8. 学院选人的时候会考虑博士和硕士的比例
  9. 逆向工程(Reverse Engineering)
  10. MBB IN CONSULTING