题目描述

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

遗憾的是,有些土地相当贫瘠,不能用来种草。并且,奶牛们喜欢独占一块草地的感觉,于是John不会选择两块相邻的土地,也就是说,没有哪两块草地有公共边。

John想知道,如果不考虑草地的总块数,那么,一共有多少种种植方案可供他选择?(当然,把新牧场完全荒废也是一种方案)

输入格式

第一行:两个整数M和N,用空格隔开。

第2到第M+1行:每行包含N个用空格隔开的整数,描述了每块土地的状态。第i+1行描述了第i行的土地,所有整数均为0或1,是1的话,表示这块土地足够肥沃,0则表示这块土地不适合种草。

输出格式

一个整数,即牧场分配总方案数除以100,000,000的余数。

输入输出样例

输入 #1

2 3

1 1 1

0 1 0

输出 #1

9

一道入门的状压dp题,但对于我这种萌新还是太难了,所以写篇博客纪念一下。。。

看到m的范围很小,我们就可以考虑对m进行状态压缩

我们设 \(f[i][j]\) 表示第\(i\)行放置情况为\(j\)的方案数.

我们就可以枚举所有的状态来进行转移

也就是 \(f[i][j] += f[i-1][k]\)

那怎么判断一个状态是否合法呢?

首先,这一行不能选相邻的两列也就是 j & (j<<1) == 0, j & (j>>1) == 0

并且还要与上一行的所选的不能有相邻的即 j & k == 0

那么怎么判断这个状态选的土地是否都合法呢?

我们可以预先处理每一行的初始状态,即对土地能不能选进行状态压缩。

当 s[i] & j == 0 就代表j这个状态可能选了不肥沃的土地。(可以画个图了解一下)

最终答案就是 \(\sum_{i=0}^{i< (1<<m)} f[n][i]\)

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int p = 1e8;
int n,m,ans,x,base[20],f[15][35000],zhuangtai[20],map[20][20];
inline int read()
{
int s = 0, w = 1; char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
while(ch >= '0' && ch <= '9'){s = s * 10+ch -'0'; ch = getchar();}
return s * w;
}
bool judge(int x)//判断x这个状态是否合法
{
if(x & (x<<1)) return 0;
if(x & (x>>1)) return 0;
return 1;
}
int main()
{
n = read(); m = read();
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
map[i][j] = read();
}
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
zhuangtai[i] = (zhuangtai[i]<<1) + map[i][j];//把一开始土地能不能选的情况进行状态压缩
}
}
base[0] = 1;
for(int i = 1; i <= m; i++) base[i] = base[i-1] * 2;
f[0][0] = 1;
for(int i = 1; i <= n; i++)
{
for(int j = 0; j < base[m]; j++)
{
if(judge(j) && ((zhuangtai[i] & j) == j))//j这个状态不能选不肥沃的土地
{
for(int k = 0; k < base[m]; k++)
{
if(((j&k) == 0) && judge(k))
{
f[i][j] += f[i-1][k];//转移
f[i][j] %= p;
}
}
}
}
}
for(int i = 0; i < base[m]; i++) ans = (ans + f[n][i]) % p;
printf("%d\n",ans);
return 0;
}

P1879 [USACO06NOV] Corn Fields G的更多相关文章

  1. 【题解】洛谷P1879 [USACO06NOV] Corn Fields(状压DP)

    洛谷P1879:https://www.luogu.org/problemnew/show/P1879 思路 把题目翻译成人话 在n*m的棋盘 每个格子不是0就是1 1表示可以种 0表示不能种 相邻的 ...

  2. 状压 DP:[USACO06NOV] Corn Fields,[USACO13NOV] No Change

    [USACO06NOV] Corn Fields (试题来源:Link ) 题目描述 Farmer John has purchased a lush new rectangular pasture ...

  3. [USACO06NOV] Corn Fields

    https://www.luogu.org/problem/show?pid=1879 题目描述 Farmer John has purchased a lush new rectangular pa ...

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

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

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

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

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

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

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

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

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

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

  9. 【洛谷P1879】玉米田Corn Fields

    玉米田Corn Fields 题目链接 此题和互不侵犯状压DP的做法类似 f[i][j]表示前i行,第i行种植(1)/不种植(0)构成的二进制数为j时的方案数 首先我们可以预处理出所有一行中没有两个相 ...

随机推荐

  1. 华为荣耀5X(畅玩版 全网通)USB调试模式如何开启教程(开发者模式 开发者选项打开)

    作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985, 前一段时间,公司买了一款华为荣耀畅玩版5X全网通,进行测试.发现 拿usb数据线连接PC电脑,无法进 ...

  2. 使用DataStax Java驱动程序的最佳实践

    引言 如果您想开始建立自己的基于Cassandra的Java程序,欢迎! 也许您已经参加过我们精彩的DataStax Academy课程或开发者大会,又或者仔细阅读过Cassandra Java驱动的 ...

  3. 开发者的福音,LR.NET模块化代码生成器

    代码生成器,是快速开发平台的核心功能之一,是一种用来帮助缺乏经验或者时间的开发者快速生成规范代码的工具,可以在极大程度上提升开发者的工作效率, 能有效避免重复工作.但稍有经验的开发者都明白,代码生成器 ...

  4. 跟着尚硅谷系统学习Docker-【day04】

    day04-20200716   p18.docker容器数据卷   docker容器中的数据,做持久化. 容器关闭以后容器内的数据就没有了. 保存到数据库或者服务器宿主机里面.   作用:容器间可以 ...

  5. ubuntu 18.04下修改python3指向

    起因 ubuntu18.04下默认带的是python3.6,但是因为需求需要升级为python3.7 步骤 安装 sudo apt install python3.7 修改环境变量 修改默认的pyth ...

  6. UEFI+MBR

    前言 传统情况下装系统的两种方案bios + mbr 或 uef i+ gpt but一直有一个疑问! 是否可以使用uefi + mbr 名词解释 硬盘格式 MBR分区:全称"Master ...

  7. win10家庭版启用远程桌面

    此电脑右键属性->远程设置->允许远程协助连接这台计算机 勾选 下载RDP Wrapper 地址:https://github.com/stascorp/rdpwrap/releases ...

  8. java时间日期的运用

    我们在使用QQ.微信等应用时,我们的手机会提示该消息时在过去的某个时间发送的,我们如何运用JAVA来实现这个功能呢? 代码如下: public class Time { public static v ...

  9. MYsql添加用户、赋予权限

    1.创建新用户 CREATE USER 'admin'@'%' IDENTIFIED BY '123456'; '%' 表示可以远程登录访问.操作 ‘localhost’ 表示只能本地登录访问.操作2 ...

  10. git修改未push和已经push的注释信息

    修改还未push的注释: git commit --amend 修改后保存退出. 刚刚push到远端还没有人其他人下载或改动的: git commit --amend1进入修改页面修改注释信息,修改后 ...