Corn Fields
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 9806   Accepted: 5185

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 3
  4  

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.

Source

 
 
        题目大意是有M×N的玉米地,但其中有些是不肥沃的,不能种植。用1来代表肥沃,0代表不肥沃。另外奶牛不喜欢挨着吃,也就是说要间隔着种植,求有几种种植方式,并将计算结果对1E8取模。
        对于0-1状态矩阵,自然而然会想到用状态压缩来做,把一行(也可以按列)的状态压缩成一个十进制数(行状态)。另种植or不种植也可以用0-1表示,并根据题目所说不能挨着种植,即这一行的某个位置种植了,下一行的同一位置就不能种植,可以知道两行的种植状态相位与要为0。
        另外说一个行种植状态有效,即相邻的格子是不能种植的,需要左移一位后与自身相位与为0,如果存在相邻种植的格子,则一定会保留位1,不可能得出0的结果,据此枚举出这些状态再进行判断。
        然而并不是每个有效的行种植状态对于每一行都有效,因为有的行存在一些位置是不能种植的,用0表示。为了方便判断和计算,我们考虑将行状态取反,即0表示肥沃,1表示不肥沃,这样只有当行种植状态和行状态相位与为0,这个种植状态才在该行有效,因为如果种在了不肥沃的格子上,相位与会保留位1,结果不为0。
        于是我们有以下设计思路:
                ①在读入时就将格子状态取反,压缩成行状态存到row[]数组里;
                ②枚举所有有效的种植状态,存到rec[]数组里,并将最大值存进去避免后面越界;
                ③先处理第一行,给dp一个基准:对于每个有效种植状态,如果在第一行也有效,计数1次;
                ④对于剩余的行,不仅要判断每个有效种植状态,还要判断两行的种植状态有没有冲突;
                ⑤对于最后一行,把每个种植状态的计数加起来,就是总的种植方法数。
  以及DP数组:dp[r][j]表示当第r行的种植状态为第j种状态时,现在玉米地的种植方案数。
  状态转移方程: dp[r][j] = dp[r-1][i] + dp[r][j], if row[i-1]&rec[i]=0 and row[i]&rec[j]=0 and rec[i]&rec[j]=0.
          即rec[i]是row[i-1]的有效行状态,且rec[j]是row[r]的有效行状态,且rec[i]和rec[j]两个行状态不发生冲突。
 
 #include <stdio.h>
#define MOD 100000000
int row[], rec[], dp[][];
int main()
{
int x=<<, k=;
for(int i=; i<x; i++) //calculate all valid states
if(!(i&(i<<))) //is a valid row state
rec[k++]=i;
rec[k]=x; int M, N, t;
scanf("%d%d", &M, &N);
for(int i=; i<M; i++)
for(int j=; j<N; j++)
scanf("%d", &t), //t = Matrix[i][j]
row[i]=(row[i]<<)|!t; //reverse row state x=<<N;
for(int i=; rec[i]<x; i++) //process first row
if(!(row[]&rec[i]))
dp[][i]=;
for(int r=; r<M; r++) //for each row
for(int i=; rec[i]<x; i++) //for each valid state for last row
if(!(row[r-]&rec[i]))
for(int j=; rec[j]<x; j++) //for each valid state for this row
if(!(row[r]&rec[j]))
if(!(rec[i]&rec[j])) //the two states are not conflict
dp[r][j]=(dp[r][j]+dp[r-][i])%MOD; int r=M-;
for(int i=; rec[i]<x; i++) //process last row
dp[r][]=(dp[r][]+dp[r][i])%MOD;
printf("%d\n", dp[r][]); return ;
}
 
        当然有进一步的空间优化:可以考虑不开二维数组,而是用两个一维数组来交换值,或者用两个动态数组,交换指针。即所谓的滚动数组。如果读者看懂了或自己实现了代码,就不难理解,不再详述。 by BlackStorm
 
 

POJ 3254. Corn Fields 状态压缩DP (入门级)的更多相关文章

  1. POJ 3254 Corn Fields(状态压缩DP)

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4739   Accepted: 2506 Descr ...

  2. POJ 3254 Corn Fields (状态压缩DP)

    题意:在由方格组成的矩形里面种草,相邻方格不能都种草,有障碍的地方不能种草,问有多少种种草方案(不种也算一种方案). 分析:方格边长范围只有12,用状态压缩dp好解决. 预处理:每一行的障碍用一个状态 ...

  3. POJ 3254 Corn Fields 状态压缩DP (C++/Java)

    id=3254">http://poj.org/problem? id=3254 题目大意: 一个农民有n行m列的地方,每一个格子用1代表能够种草地,而0不能够.放牛仅仅能在有草地的. ...

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

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

  5. POJ 3254 Corn Fields状态压缩DP

    下面有别人的题解报告,并且不止这一个状态压缩题的哦···· http://blog.csdn.net/accry/article/details/6607703 下面是我的代码,代码很挫,绝对有很大的 ...

  6. [ACM] POJ 3254 Corn Fields(状态压缩)

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8062   Accepted: 4295 Descr ...

  7. poj 3254 Corn Fields 国家压缩dp

    意甲冠军: 要在m行n陆行,有一些格您可以种树,别人做不到的.不相邻的树,我问了一些不同的共同拥有的法律. 分析: 从后往前种,子问题向父问题扩展,当种到某一格时仅仅有他和他后面的n-1个格子的情况对 ...

  8. POJ 3254 Corn Fields 状态压缩

    这题对我真的非常难.实在做不出来,就去百度了,搜到了一种状压DP的方法.这是第一种 详细见凝视 #include <cstdio> #include <cstring> #in ...

  9. poj 3254 Corn Fields_状态压缩dp

    感谢:http://www.cnblogs.com/ka200812/archive/2011/08/11/2135607.html 让我搞懂了. #include <iostream> ...

随机推荐

  1. 【.net深呼吸】(WCF)OperationContextScope 的用途

    一个WCF服务可以实现多个服务协定(服务协定实为接口),不过,每个终结点只能与一个服务协定关联,并指定调用的唯一地址.那么,binding是干吗的?binding是负责描述通信的协议,以及消息是否加密 ...

  2. 页面width与height使用百分比来划分不起作用解决办法--记录六

    有时候你写 <div style="width:80%;height:100%;border:1px solid red"></div> <div s ...

  3. OPEN CASCADE编译视频

    为了帮助OPEN CASCADE新手顺利编译OPEN CASCADE源码,特录制了一个视频, 有了这个视频,OPEN CASCADE的编译再也不麻烦啦!

  4. webpack+react+es6开发模式

    一.前言 实习了两个月,把在公司用到的前端开发模式做个简单的整理.公司里前端开发模式webpack+react+redux+es6,这里去掉了redux. webpack, react, redux等 ...

  5. 计算机程序的思维逻辑 (43) - 剖析TreeMap

    40节介绍了HashMap,我们提到,HashMap有一个重要局限,键值对之间没有特定的顺序,我们还提到,Map接口有另一个重要的实现类TreeMap,在TreeMap中,键值对之间按键有序,Tree ...

  6. 浅析MySQL复制

    MySQL的复制是基于binlog来实现的. 流程如下 涉及到三个线程,主库的DUMP线程,从库的IO线程和SQL线程. 1. 主库将所有操作都记录到binlog中.当复制开启时,主库的DUMP线程根 ...

  7. 数据结构:二叉查找树(C语言实现)

    数据结构:二叉查找树(C语言实现) ►写在前面 关于二叉树的基础知识,请看我的一篇博客:二叉树的链式存储 说明: 二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: 1.若其左子树不空,则左子树上 ...

  8. Linux平台oracle 11g单实例 + ASM存储 安装部署 快速参考

    操作环境:Citrix虚拟化环境中申请一个Linux6.4主机(模板)目标:创建单机11g + ASM存储 数据库 1. 主机准备 2. 创建ORACLE 用户和组成员 3. 创建以下目录并赋予对应权 ...

  9. ORA 各种oraclesql错误

    ORA-00001: 违反唯一约束条件 (.) ORA-00017: 请求会话以设置跟踪事件 ORA-00018: 超出最大会话数 ORA-00019: 超出最大会话许可数 ORA-00020: 超出 ...

  10. 从.NET和Java之争谈IT这个行业

    一.有些事情难以回头 开篇我得表名自己的立场:.NET JAVA同时使用者,但更加偏爱.NET.原因很简单 1.NET语言更具开放性,从开源协议和规范可以看出; 2.语言更具优势严谨; 3.开发工具V ...