我要开状压dp的坑了。。直播从入门到放弃系列。。

那就先拿一道状压dp的水题练练手吧。。

然后就找到了这一道。。这道题使我清醒地认识到阻碍我的不是算法,而是视力= =

传送门:
poj:http://poj.org/problem?id=3254
luogu:https://www.luogu.org/problem/show?pid=1879.233333 (雾

题目大意:

n*m的01矩阵上放棋子(牛),不能放到相邻格子,问方案数。(啥也不放算一种方案(然而我视力好到看到这一点了))

题目分析:

都说了状压dp 水题肯定要用仙人图上在线分支定界启发式带花树上下界最小费用流解决问题啊~(什么鬼)

我们可以看出,我们可以通过i-1行的放法转移出第i行的放法,所以这题是dp无疑。状态转移方程:

第i行状态为j(j合法):
f[i][j]=sigma(f[i-1][k]) (k与j不冲突)

然而j是一种状态而不是一个数字。所以这就是本题不同于传统dp的地方,我们要状压

嗯,状压,什么是状压? 状态压缩
那什么是状态压缩?
以本题为例,我们发现n,m的范围很小(其实有一维的范围很小就可以O(∩_∩)O)
而每一个格子上都只有放牛和不放牛两种选择,所以……
既然是学信息的,我们可以用二进制来表示啊~

我们可以用不超过12位二进制来表示当前行中的状态,从而完成了压缩。。 还有可爱的位运算为伴哦~

大体来说就是这样。。

如何筛选合法状态?

题目中,对于同一行中相邻的情况,我们可以用(i&(i-1))解决..
对于行之间相邻的情况,把两行按位与一下即可。。

每一行枚举复杂度不会爆炸吗?

(本题不存在此担心,2^12^2勉强能跑过,但有些题是30左右就hold不住了..)
这个放心即可。。我们可以先预处理。。然后发现可枚举的状态其实是十分有限的..

预处理大概是长介个样纸:

for(int i=0;i<1<<m;i++)
if(!(i&(i<<1))){
op[cnt++]=i;
}

经实测,在2^12=4096个状态中,能在1行中合法存在的只有377个。。(要算错了可以来纠正我_ (:з」∠) _反正我日常算错。。不过算错应该不会差多少)

总之不会爆炸,而且还跑得很快就对了~~

啰嗦了半天,还是上代码吧。。

代码实现

#include <cstdio>
#include <cstring> int op[380],cnt,n,m,ans;
int f[13][380],za[13]; void dp(){
for(int i=0;i<1<<m;i++)
if(!(i&(i<<1))){
op[cnt]=i;
if(!(i&za[0])) f[0][cnt]=1;
cnt++;
}
for(int i=1;i<n;i++)
for(int j=0;j<cnt;j++){
if(op[j]&za[i]) continue;
for(int k=0;k<cnt;k++)
if(!(op[j]&op[k]))
f[i][j]+=f[i-1][k];
}
} int main(){
scanf("%d%d",&n,&m);
ans=0; cnt=0;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
int k; scanf("%d",&k);
if(!k) za[i]|=(1<<j);
}dp();
for(int i=0;i<cnt;i++) ans=(ans+f[n-1][i])%100000000;
printf("%d\n",ans);
}

大概就这样吧。。

文末彩蛋
为什么我说这题卡视力了呢?
因为我前几遍硬是没看见取模~
还到luogu下了一次数据才看出来。。
我多半是完了_ (:з」∠) _

【学术篇】状态压缩动态规划——POJ3254/洛谷1879 玉米田Corn Field的更多相关文章

  1. 洛谷 P1879 玉米田Corn Fields 题解

    题面 一道思维难度不大的状态压缩,也并不卡常,但细节处理要格外注意: f[i][j]表示前i行最后一行状态是j的方案数 #include <bits/stdc++.h> #define p ...

  2. 洛谷 P1879 玉米田(状压DP入门题)

    传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 题解: 相关变量解释: int M,N; int plant[maxn][maxn];/ ...

  3. 洛谷P1879 玉米田

    题目描述 农场主John新买了一块长方形的新牧场,这块牧场被划分成M行N列(1 ≤ M ≤ 12; 1 ≤ N ≤ 12),每一格都是一块正方形的土地.John打算在牧场上的某几格里种上美味的草,供他 ...

  4. 状态压缩动态规划 状压DP

    总述 状态压缩动态规划,就是我们俗称的状压DP,是利用计算机二进制的性质来描述状态的一种DP方式 很多棋盘问题都运用到了状压,同时,状压也很经常和BFS及DP连用,例题里会给出介绍 有了状态,DP就比 ...

  5. BZOJ_4197_[Noi2015]寿司晚宴_状态压缩动态规划

    BZOJ_4197_[Noi2015]寿司晚宴_状态压缩动态规划 Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被 ...

  6. 洛谷P1879 [USACO06NOV]玉米田Corn Fields(状压dp)

    洛谷P1879 [USACO06NOV]玉米田Corn Fields \(f[i][j]\) 表示前 \(i\) 行且第 \(i\) 行状态为 \(j\) 的方案总数.\(j\) 的大小为 \(0 \ ...

  7. 状压DP【洛谷P1879】 [USACO06NOV]玉米田Corn Fields

    P1879 [USACO06NOV]玉米田Corn Fields 农场主John新买了一块长方形的新牧场,这块牧场被划分成M行N列(1 ≤ M ≤ 12; 1 ≤ N ≤ 12),每一格都是一块正方形 ...

  8. C++ 洛谷 P1879 [USACO06NOV]玉米田Corn Fields

    没学状压DP的看一下 合法布阵问题  P1879 [USACO06NOV]玉米田Corn Fields 题意:给出一个n行m列的草地(n,m<=12),1表示肥沃,0表示贫瘠,现在要把一些牛放在 ...

  9. 洛谷 P1879 [USACO06NOV]玉米田Corn Fields 题解

    P1879 [USACO06NOV]玉米田Corn Fields 题目描述 Farmer John has purchased a lush new rectangular pasture compo ...

随机推荐

  1. NX二次开发-UFUN由工程图视图tag获取图纸页tag UF_DRAW_ask_drawing_of_view

    #include <uf.h> #include <uf_draw.h> #include <uf_drf.h> #include <uf_obj.h> ...

  2. GTK+/GNOME编程(一)

    1.开发环境:安装GTK+/GNOME库 #apt-get install gtk+-3.0                   (安装GTK+库文件) #apt-get install gnome- ...

  3. Go语言中new()和 make()的区别详解

    概述 Go 语言中的 new 和 make 一直是新手比较容易混淆的东西,咋一看很相似.不过解释两者之间的不同也非常容易. new 的主要特性 首先 new 是内建函数,你可以从 http://gol ...

  4. 数据结构C++版-队列

    一.概念 分类: 二.补充说明 1.<面向对象的队列设计>课程问答: 首先要明确数据结构和数据存储结构的概念. 数据结构是指数据对象之间的逻辑关系,例如二叉树,队列,栈等,而数据存储结构是 ...

  5. 创建 Angular 8.0 项目

    创建 Angular 8.0 项目,首先确保已经安装了 nodejs,如果没有安装,请看这篇文章安装:node.js 安装 1.新建一个空文件夹 angularproject,作为工作区 2.安装 A ...

  6. 『BASH』——Learn BashScript from Daniel Robbins——[003]

    ABSTRACT: Daniel Robbins is best known as the creator of Gentoo Linux and author of many IBM develop ...

  7. 初探分布式环境的指挥官ZooKeeper

    目录 1. 从单机到集群,分布式环境中的挑战 1.1 集中式的特点 1.2 集中式的痛点 1.3 从单体到SOA的转变 1.4 分布式服务总体框架 1.5 分布式应用概述 2. ZK基本概念及核心原理 ...

  8. Python3入门机器学习经典算法与应用✍✍✍

    Python3入门机器学习经典算法与应用 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题,大家看的 ...

  9. echarts数据变了不重新渲染,以及重新渲染了前后数据会重叠渲染的问题

    1.echarts数据变了但是视图不重新渲染 新建Chart.vue文件 <template>  <p :id="id" :style="style&q ...

  10. Linux服务器下对Oracle数据库expdp(导出)和impdp(导入)

    紧接上篇文章,Oracle数据库架构已经创建完成,我的需求是:将老服务器上的数据库迁移到新的数据库上. 这就用到impdp(导入)操作. 要想实现对新数据库的impdp(导入)工作, 首先需要从老的数 ...