POJ Corn Fields 状态压缩DP基础题
题目链接:http://poj.org/problem?id=3254
题目大意(名称什么的可能不一样,不过表达的意思还是一样的):
种玉米
王小二从小学一年级到现在每次考试都是班级倒数第一名,他的爸爸王大强觉得读书对于王小二来说应该是没有出路了,于是决定让王小二继承自己的衣钵,从事一份非常有前途的工作——种玉米。王大强是一位富有的农场主,他拥有一块 M*N 平方米的矩形田地专门用来种玉米(1<=M,N<=12)。这个玉米地被分成了 M*N 个,每个格子是一个大小为1平方米的格子。这块玉米地中有一些格子因为还没有开垦,所以上面长满了岩石,所以这些格子是不适合种玉米的。相邻的格子也是不能同时种玉米的,因为如果这么做了的话,两个格子区域的玉米因为相互抢夺土壤里面的资源结果会都长不好。
虽然王小二的成绩不好,但是他是一个喜欢思考的人,他想要知道一共有多少种可行的方式来种玉米。
输入
第一行包括两个正数M和N。
接下来M行每行包含N个整数,数字1表示这个格子是适合种玉米的,数字0表示这个格子不适合种玉米。
输出
输出一个整数,表示种玉米的方案数。(除 100,000,000 取模)
样例输入
2 3
1 1 1
0 1 0
样例输出
9
题目分析:这道题目可以用状态压缩DP来处理。
dp[i][j] 表示第i行的状态取为j的时候的方案总数,那么这个j的状态是什么意思呢?
j虽然是一个整数,但是它其实表示的是一行的所有二进制状态。
比如,如果我们某一行的三个格子分别是:种、不种、种,我们用 1 表示“种”,用 0 表示“不种”, 那么这一行其实可以表示成 1,0,1 对应的二进制数就是 101 ,这个数对应的十进制的数就是 1*4+0*2+1*1 = 5,
我们还要过滤一下每一行的状态,第i行的状态j成立的条件是:
- j对应的状态上没有在有岩石的格子上种玉米;
- j对应的状态不会有连续的两列上种玉米。
这两点我在代码上面有比较明确的体现。
然后我们就可以得到状态转移方程:
dp[i][j] = 1, 其中i==0(第0行),j是第i行的合理状态(满足上面提到的两个条件)
dp[i][j] = sum(dp[i-1][k]),其中i>0,j是第i行的合理状态,k是第i-1行的所有合理状态的集合,并且j和k状态满足关系式:j&k==0,对应的字面意思就是不存在连续的两行同一列都种着玉米
最后的结果就是 sum(dp[M-1][j]),其中j对应第M-1的所有合理状态。
代码:
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
const int maxn = 13;
const int MOD = 100000000;
int M, N, dp[maxn][1<<maxn], g[maxn][maxn];
vector<int> states[maxn];
void test() {
for (int i = 0; i < M; i ++) {
cout << (i+1) << "(" << states[i].size() << "): ";
int sz = states[i].size();
for (int j = 0; j < sz; j ++) {
if (j) cout << ",";
cout << states[i][j];
}
cout << endl;
}
cout << "check:" << endl;
for (int i = 0; i < states[M-1].size(); i ++) {
if (dp[M-1][i]) {
cout << "\t" << i << " : " << dp[M-1][i] << endl;
}
}
}
int main() {
while (cin >> M >> N) {
memset(dp, 0, sizeof(dp));
for (int i = 0; i < M; i ++) {
for (int j = 0; j < N; j ++) {
cin >> g[i][j];
}
}
for (int i = 0; i < M; i ++) {
states[i].clear();
for (int j = 0; j < (1<<N); j ++) {
bool flag = true;
// 判断是否在岩石上种了玉米
for (int k = 0; k < N; k ++) {
if (g[i][k] == 0 && j&(1<<k)) {
flag = false;
break;
}
}
// 判断是否相邻的格子都种了玉米
if (flag) {
for (int k = 0; k < N-1; k ++) {
if (j&(1<<k) && j&(1<<(k+1))) {
flag = false;
break;
}
}
}
if (flag) {
states[i].push_back(j);
}
}
}
int sum = 0;
for (int i = 0; i < M; i ++) {
int sz = states[i].size();
for (int j = 0; j < sz; j ++) {
int p = states[i][j];
if (i == 0) dp[i][p] = 1;
else {
int sz2 = states[i-1].size();
for (int k = 0; k < sz2; k ++) {
int q = states[i-1][k];
if (!(p&q)) {
dp[i][p] += dp[i-1][q];
dp[i][p] %= MOD;
}
}
}
if (i == M-1) {
sum += dp[i][p];
sum %= MOD;
}
}
}
cout << sum << endl;
// test();
}
return 0;
}
POJ Corn Fields 状态压缩DP基础题的更多相关文章
- poj Corn Fields 状态压缩dp。
Corn Fields Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5763 Accepted: 3052 Descr ...
- POJ 3254 Corn Fields(状态压缩DP)
Corn Fields Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4739 Accepted: 2506 Descr ...
- POJ 3254 Corn Fields (状态压缩DP)
题意:在由方格组成的矩形里面种草,相邻方格不能都种草,有障碍的地方不能种草,问有多少种种草方案(不种也算一种方案). 分析:方格边长范围只有12,用状态压缩dp好解决. 预处理:每一行的障碍用一个状态 ...
- POJ3254 - Corn Fields(状态压缩DP)
题目大意 给定一个N*M大小的土地,土地有肥沃和贫瘠之分(每个单位土地用0,1来表示贫瘠和肥沃),要求你在肥沃的单位土地上种玉米,如果在某个单位土地上种了玉米,那么与它相邻的四个单位土地是不允许种玉米 ...
- POJ 3254. Corn Fields 状态压缩DP (入门级)
Corn Fields Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9806 Accepted: 5185 Descr ...
- POJ 3254 Corn Fields 状态压缩DP (C++/Java)
id=3254">http://poj.org/problem? id=3254 题目大意: 一个农民有n行m列的地方,每一个格子用1代表能够种草地,而0不能够.放牛仅仅能在有草地的. ...
- POJ 3254 Corn Fields状态压缩DP
下面有别人的题解报告,并且不止这一个状态压缩题的哦···· http://blog.csdn.net/accry/article/details/6607703 下面是我的代码,代码很挫,绝对有很大的 ...
- poj - 3254 Corn Fields (状态压缩dp入门)
http://poj.org/problem?id=3254 参考:http://blog.csdn.net/accry/article/details/6607703 农夫想在m*n的土地上种玉米, ...
- 【poj3254】Corn Fields 状态压缩dp
AC通道:http://vjudge.net/problem/POJ-3254 [题目大意] 农夫约翰购买了一处肥沃的矩形牧场,分成M*N(1<=M<=12; 1<=N<=12 ...
随机推荐
- springboot开发人员工具(自动重启及相关的配置)
导入依赖: <dependencies> <dependency> <groupId>org.springframework.boot</groupId> ...
- Tensorflow细节-P80-深度神经网络
1.本节多为复习内容,从以下图片可见一般: 2.学会使用 from numpy.random import RandomState 然后 rdm = RandomState(1) dataset_si ...
- 本地存储API
一.定义 随着互联网的快速发展,基于网页的应用越来越普遍,同时也变得越来越复杂,为了满足各种各样的需求,会经常在本地存储大量的数据,HTML5规范提出了相关解决方案 本地存储设置读取方便,容量较大,s ...
- LibreOJ #6191. 「美团 CodeM 复赛」配对游戏
二次联通门 : LibreOJ #6191. 「美团 CodeM 复赛」配对游戏 /* LibreOJ #6191. 「美团 CodeM 复赛」配对游戏 概率dp */ #include <cs ...
- 模板 - 数学 - 数论 - Min_25筛
终于知道发明者的正确的名字了,是Min_25,这个筛法速度为亚线性的\(O(\frac{n^{\frac{3}{4}}}{\log x})\),用于求解具有下面性质的积性函数的前缀和: 在 \(p\) ...
- mysql 导出数据或结构
mysql 导出数据或结构 语法说明 mysqldump -h 数据库地址 -u用戶名 -p密码 -d 数据库名 表名 > 脚本名; 导出整个数据库结构和数据 mysqldump -uroot ...
- 服务器部署docker
docker简介 可以把docker是一个容器,可以让开发者将自己的项目部署到这个容器中,最常用的场景是将自己的后端项目部署到服务器的时候会将其打入docker镜像中,可以理解为一个开销更小的虚拟机. ...
- 我们一起分析一下这个刚刚修复的RDP漏洞CVE-2019-0708
写在前面的话 在微软今年五月份的漏洞更新安全公告中,提到了一个跟远程桌面协议(RDP)有关的漏洞.我们之所以要在这里专门针对这个漏洞进行分析,是因为这个漏洞更新涉及到Windows XP以及其他多个W ...
- MGI数据库挖掘 | MGI-Mouse Genome Informatics | InWeb database
做生物信息,遗传发育,分析数据的时候总是要narrow down分析范围,高通量数据尤其是基因表达,在庞大的confounder面前,缩小分析范围是必须的,否则你会一直在混沌中游荡. 看一篇文章:20 ...
- Java项目登录报Session Error
在web.xml文件添加下面红色代码即可,注意:添加代码后,格式化一下代码. <servlet> <servlet-name>dwr-invoker</se ...