状压暴力显然可做。但是数据出的再大一点就要稳T了。理论$O(n4^m)$,只不过实际跑不满。

考虑用轮廓线DP,设$f(i,j,S)$为处理到$(i,j)$时候(这格还不确定)的轮廓线为$S$的情况(相当于把$(i,1\sim j-1)$和$(i-1,j\sim m)$的$m$个数用$S$压起来)下有多少种合法方案,然后考虑$(i,j)$这个格子填什么。

不管怎么样,这格都可以填0,将这个推向$f(i,j+1,S')$。如果左一格或上一格填了1或者这格有障碍,那不能填1,否则可以填1,同理推向$f(i,j+1,S'')$。

这里的$S'和S''$是位运算将第$j$位进行$0/1$变换的。

注意考虑细节:一行的轮廓线推完($j$循环到$m$结束后)的这个状态是要作为下一行的起始状态的。也就是$f(i,m,S)$应当推向$f(i+1,1,S')$。

我们可以通过直接滚动数组来一格一格往下推,避免换行之类的操作,详见code。

其次,这样DP不需要考虑相邻合不合法,因为我在填的时候推向后面的状态这个操作已经是保证他合法的了,即使是枚举出了不合法的,他的方案数也会是$0$,也没办法有累加作用。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define dbg(x) cerr << #x << " = " << x <<endl
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int P=1e8;
int mp[][],f[][<<];
int m,n,now,tmp,ans; int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
read(n),read(m);
for(register int i=;i<=n;++i)for(register int j=;j<=m;++j)read(mp[i][j]);
f[][]=;
for(register int i=;i<=n;++i){
for(register int j=;j<=m;now^=,++j){
for(register int k=;k<<<m;++k)if(f[now][k]){
int p2=k&(<<j-),p1=j==?:k&(<<j-);
tmp=p2?k^(<<j-):k,f[now^][tmp]+=f[now][k],f[now^][tmp]>=P&&(f[now^][tmp]-=P);
if(mp[i][j]&&!p1&&!p2)
tmp=k|(<<j-),f[now^][tmp]+=f[now][k],f[now^][tmp]>=P&&(f[now^][tmp]-=P);
f[now][k]=;
}
}
}
for(register int k=;k<<<m;++k)ans+=f[now][k],ans>=P&&(ans-=P);
return printf("%d\n",ans),;
}

理论$O(nm2^m)$。

P1879 [USACO06NOV]玉米田Corn Fields[轮廓线DP]的更多相关文章

  1. P1879 [USACO06NOV]玉米田Corn Fields(状压dp)

    P1879 [USACO06NOV]玉米田Corn Fields 状压dp水题 看到$n,m<=12$,肯定是状压鸭 先筛去所有不合法状态,蓝后用可行的状态跑一次dp就ok了 #include& ...

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

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

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

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

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

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

  5. 洛谷P1879 [USACO06NOV]玉米田Corn Fields (状态压缩DP)

    题目描述 Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ...

  6. 洛谷P1879 [USACO06NOV]玉米田Corn Fields【状压DP】题解+AC代码

    题目描述 Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ...

  7. P1879 [USACO06NOV]玉米田Corn Fields (状压dp入门)

    题目链接: https://www.luogu.org/problemnew/show/P1879 具体思路: 我们可以先把所有合法的情况枚举出来,然后对第一行判断有多少种情况满足,然后对于剩下的行数 ...

  8. P1879 [USACO06NOV]玉米田Corn Fields 状压dp/插头dp

    正解:状压dp/插头dp 解题报告: 链接! ……我真的太菜了……我以为一个小时前要搞完的题目调错误调了一个小时……90分到100我差不多搞了一个小时…… 然后这题还是做过的……就很气,觉得确实是要搞 ...

  9. P1879 [USACO06NOV]玉米田Corn Fields

    题目描述 Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ...

随机推荐

  1. python基础知识(列表详解)

    列表(list) 列表中可以存入整数.实数.布尔值.字符串.序列.对象 可变序列 列表  []  元素间隔用   ,号分隔 列表的创建和删除 使用赋值运算符直接创建列表 listname = [元素1 ...

  2. <转>经典测试用例:电梯、杯子、桌子、洗衣机

    1.测试项目:电梯 需求测试:查看电梯使用说明书.安全说明书等 界面测试:查看电梯外观 功能测试:测试电梯能否实现正常的上升和下降功能.电梯的按钮是否都可以用: 电梯门的打开,关闭是否正常:报警装置是 ...

  3. Django模板系统-母板和继承

    母板和继承 母版 html页面,提取多个页面的公共部分 定义多个block块,需要让子页面进行填充 <head> {% block page-css %} {% endblock %} & ...

  4. linux6 下设置oracle自启动(单实例)

    操作系统启动过程中,读取/etc/oratab文件,判断是否有哪些数据库是需要自动启动的(N代表不自动启动,Y代表自动启动) elan:/u01/app/oracle/product/10.2.0:Y ...

  5. Largest Number At Least Twice of Others

    In a given integer array nums, there is always exactly one largest element. Find whether the largest ...

  6. sqlserver安装和踩坑经历

    sqlserver安装和踩坑经历 下载 下载 安装 大致是按照这个来的 安装教程 出错 windows系统安装软件弹出"Windows installer service could not ...

  7. python中进程的几种创建方式

    在新创建的子进程中,会把父进程的所有信息复制一份,它们之间的数据互不影响. 使用os.fork()创建 该方式只能用于Unix/Linux操作系统中,在windows不能用. import os # ...

  8. spark教程(10)-sparkSQL

    sparkSQL 的由来 我们知道最初的计算框架叫 mapreduce,他的缺点是计算速度慢,还有一个就是代码比较麻烦,所以有了 hive: hive 是把类 sql 的语句转换成 mapreduce ...

  9. linux 下如何将网页版应用生成桌面图标

    使用linux mint已经两年了,很多国民应用,都没有Linux版,但是这些应用都有网页版,今天就说下最简单的将网页应用变成桌面应用,无需配置,安装任何插件.以微信为例; 首先,在谷歌浏览器打开网页 ...

  10. 2016 计蒜之道 初赛 第一场 D 青云的机房组网方案 (虚树)

    大意: 给定树, 点$i$的点权为$a_i$, 求$\sum\limits_{a_i \perp a_j}dis(i,j)$ 中等难度可以枚举每条边的贡献, 维护子树内每个数出现次数$a$, 转化为求 ...