Corn Fields
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 6321   Accepted: 3361

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  

题目大意:

农夫有一块地,被划分为m行n列大小相等的格子,其中一些格子是可以放牧的(用1标记),农夫可以在这些格子里放牛,其他格子则不能放牛(用0标记),并且要求不可以使相邻格子都有牛。现在输入数据给出这块地的大小及可否放牧的情况,求该农夫有多少种放牧方案可以选择

解析:

状态压缩动态规划

首先介绍一下什么是状态压缩,这里引用一句神犇的话,我认为总结得很好:

这种用一个数来表示一组数,以降低表示状态所需的维数的解题手段,就叫做状态压缩。  ------@外出散步

单从语言上理解可能有点抽象,我来举个例子。

比如就这一道题而言,如果用普通DP的方式做,最终可能变成用dp[i][i+1][i+2]......[m]来表示一行的状态。当然,如果你真的这样做,时间和空间上与状压DP的效果应该差不多,但如果比代码量的话,我就只能呵呵了。

那么问题来了,怎样进行状态压缩呢?这里我们可以根据不同题目的实际情况灵活地运用位运算与不同的进制来解决。对于这道题,我们就能运用二进制来表示一行的状态。

根据样例,我们可以把第一行的状态表示为111表示第一行每一个位置都能放,把第二行的状态表示为010表示第二行只有第二个位置能放,这样我们只用将每一个状态存入一个数组里面就能成功地压缩状态,且每一个状态所表示的二进制不同,我们就不用担心重复的问题。

判断一道题是否是状压DP的很常用方法是观察这道题的数据范围,一般用状压DP做的题目数据范围一般都在几十(再小就直接用暴力了。。。)

回到这一道题,我们就可以设dp[i][state[k]]表示第i行采用第k种方案得到的可行方案总数,很明显状态转移方程为:

dp[i][state[k]]=dp[i-1][k1]+dp[i-1][k2]+......dp[i-1][ktot]。

于是最终的答案ans=dp[n][k1]+dp[n][k2]+......dp[n][ktot]。

细节问题参见代码:

#include <bits/stdc++.h>
using namespace std;const int mod=100000000;
const int Max=1010;
int n,m,ans,tot;
int num[Max],state[Max];  //num:每行实际情况 state:所有可能方案
int dp[20][Max]; inline void clean()    //清空
{ans=0;tot=0;memset(num,0,sizeof(num));memset(state,0,sizeof(state));memset(dp,0,sizeof(dp));
}inline int check1(int state,int id)//判断与实际情况是否匹配
{if((state&num[id])) return 0;else return 1;
}inline int check2(int x)//判断本身条件是否匹配
{if(x&(x<<1)) return 0;else return 1;
}inline void pre()//计算方案数
{int total=(1<<m);for(int i=0;i<total;i++){if(check2(i)) state[++tot]=i;}
}int main()
{//freopen("lx.in","r",stdin);//freopen("lx.out","w",stdout);while(scanf("%d%d",&n,&m)!=EOF){clean();pre();int exist;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){scanf("%d",&exist);if(exist==0) num[i]+=1<<(m-j);    //反存:若不能放设为1。后面会有解释}}for(int i=1;i<=tot;i++)              //初始化if(check1(state[i],1)) dp[1][i]=1;for(int i=2;i<=n;i++)for(int k=1;k<=tot;k++)if(check1(state[k],i))     //判断第i行的方案是否符合实际情况for(int j=1;j<=tot;j++)if(check1(state[j],i-1))      //判断第i-1行的方案是否符合实际情况if(!(state[k]&state[j]))     //判断第i行的方案与第i-1的方案是否冲突dp[i][k]=(dp[i][k]+dp[i-1][j])%mod;    //累加for(int i=1;i<=tot;i++) ans=(ans+dp[n][i])%mod;   //累加得答案cout<<ans<<"\n";}return 0;
}

POJ3254 状压DP模板相关推荐

  1. 【每日DP】day2、P1879 [USACO06NOV]Corn Fields G玉米地(状压DP模板题)难度⭐⭐⭐★

    昨天的每日DP我还在写01背包,今天就到状压DP了,真刺激. P1879 [USACO06NOV]Corn Fields G 题目链接 输入 2 3 1 1 1 0 1 0 输出 9 一道简单的状压D ...

  2. poj3254/洛谷P1896 状压dp

    http://poj.org/problem?id=3254 https://www.luogu.org/problemnew/show/P1896 把这两题放在一起,解题思路差不多.以POJ的为例 ...

  3. [状压dp] 蒙德里安的梦想(模板题+状压dp)

    文章目录 0. 前言 1. 状压dp 模板题 0. 前言 状压 dp 就是采用二进制数保存状态,方便进行位运算操作.例如 八皇后.八数码问题也都是采用了状态压缩的思想来使用一个二进制数唯一对应集合中的 ...

  4. [状压dp] 最短Hamilton路径(模板题+状压dp)

    文章目录 0. 前言 1. 状压dp 模板题 0. 前言 状压 dp 就是采用二进制数保存状态,方便进行位运算操作.例如 八皇后.八数码问题也都是采用了状态压缩的思想来使用一个二进制数唯一对应集合中的 ...

  5. UVA10296 Jogging Trails(中国邮递员问题)(欧拉回路、一般图最大权匹配 / 状压DP)

    整理的算法模板合集: ACM模板 目录 思路 UVA10296 Jogging Trails 题目翻译: 给你n个点,m条无向边,每条边有一定的距离数值,构造成一个连通图.问从任意一点出发,遍历所有的 ...

  6. BZOJ 4000: [TJOI2015]棋盘( 状压dp + 矩阵快速幂 )

    状压dp, 然后转移都是一样的, 矩阵乘法+快速幂就行啦. O(logN*2^(3m)) ------------------------------------------------------- ...

  7. 动态规划 —— 状压 DP

    [概述] 通常将以一个集合内的元素信息作为状态且状态总数为指数级别的动态规划称为状态压缩动态规划. 其是一类以集合信息为状态的特殊的动态规划问题,主要有传统集合动态规划与基于连通性状态压缩的动态规划两 ...

  8. 【算法竞赛学习笔记】状压DP

    title : 状压DP date : 2022-3-5 tags : ACM,图论,动态规划 author : Linno 状压DP 状态压缩,是利用二进制数的性质对问题进行优化的一种算法,经常与搜 ...

  9. [状压dp] 小国王(状压dp+下标映射技巧)

    文章目录 0. 前言 1. 状压dp+棋盘式(基于连通性) 0. 前言 相关: [状压dp] 蒙德里安的梦想(模板题+状压dp) 1. 状压dp+棋盘式(基于连通性) 1064. 小国王 思路: 状压 ...

最新文章

  1. 三插头内部结构图_10寸三防加固平板电脑 条码数据采集器 工业级耐摔防爆 高清屏幕带网口串口 支持航空插头...
  2. CentOS安装和配置Mysql
  3. vb调用vc dll
  4. 虾皮如何注册店铺_虾皮跨境电商怎样注册店铺?做(shopee)虾皮电商靠谱吗
  5. http通信协议的基本原理
  6. BigDecimal转String,int,double及简单操作运算、方法
  7. python判断一个数是否是质数
  8. bll调用mysql存储过程_SQL Server的存储过程或自定义函数调用Com组件
  9. 编译GDAL使用最新的HDF库配置文件
  10. dcp7080d怎么加墨粉_兄弟7080打印机怎么加粉
  11. CSS 使用多张背景图
  12. Facebook背后的软件
  13. 一个比 ClickHouse 还快的开源数据库
  14. java用account类型定义两个变量_java 编程
  15. 微信公众号的二次开发(二 自定义菜单的创建)
  16. 项目绩效考核体系指标建设图表
  17. 【毕业设计_课程设计】基于Android Studio平台的测量程序设计与实现
  18. springboot 整合 mongodb 增删改查 第二篇
  19. 现在做淘客晚了吗?自媒体淘客告诉你答案
  20. 服务器攻击类型--CC攻击

热门文章

  1. 【Win】KMS 激活命令记录
  2. 【经验分享】突然我的SM.MS的图床没法访问了(内附解决方法)
  3. 将CAD图纸中的线型和文字样式合并的方法技巧(二)
  4. kbhit linux windows通用,_kbhit() for Linux
  5. 席慕容的诗歌——《我愿为莲》
  6. 【总结】线性代数的本质 - 3
  7. Lubuntu下启用Compiz
  8. 电气器件系列二十四:电子式压力传感器PPG-D(1)
  9. 不同CPU的MATLAB性能表现的简单对比方法
  10. python进行谱曲_使用LSTM-GAN为歌词谱曲