题目描述

农场主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]\)

代码

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. using namespace std;
  5. const int p = 1e8;
  6. int n,m,ans,x,base[20],f[15][35000],zhuangtai[20],map[20][20];
  7. inline int read()
  8. {
  9. int s = 0, w = 1; char ch = getchar();
  10. while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
  11. while(ch >= '0' && ch <= '9'){s = s * 10+ch -'0'; ch = getchar();}
  12. return s * w;
  13. }
  14. bool judge(int x)//判断x这个状态是否合法
  15. {
  16. if(x & (x<<1)) return 0;
  17. if(x & (x>>1)) return 0;
  18. return 1;
  19. }
  20. int main()
  21. {
  22. n = read(); m = read();
  23. for(int i = 1; i <= n; i++)
  24. {
  25. for(int j = 1; j <= m; j++)
  26. {
  27. map[i][j] = read();
  28. }
  29. }
  30. for(int i = 1; i <= n; i++)
  31. {
  32. for(int j = 1; j <= m; j++)
  33. {
  34. zhuangtai[i] = (zhuangtai[i]<<1) + map[i][j];//把一开始土地能不能选的情况进行状态压缩
  35. }
  36. }
  37. base[0] = 1;
  38. for(int i = 1; i <= m; i++) base[i] = base[i-1] * 2;
  39. f[0][0] = 1;
  40. for(int i = 1; i <= n; i++)
  41. {
  42. for(int j = 0; j < base[m]; j++)
  43. {
  44. if(judge(j) && ((zhuangtai[i] & j) == j))//j这个状态不能选不肥沃的土地
  45. {
  46. for(int k = 0; k < base[m]; k++)
  47. {
  48. if(((j&k) == 0) && judge(k))
  49. {
  50. f[i][j] += f[i-1][k];//转移
  51. f[i][j] %= p;
  52. }
  53. }
  54. }
  55. }
  56. }
  57. for(int i = 0; i < base[m]; i++) ans = (ans + f[n][i]) % p;
  58. printf("%d\n",ans);
  59. return 0;
  60. }

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. Python 逆向抓取 APP 数据

    今天继续给大伙分享一下 Python 爬虫的教程,这次主要涉及到的是关于某 APP 的逆向分析并抓取数据,关于 APP 的反爬会麻烦一些,比如 Android 端的代码写完一般会进行打包并混淆加密加固 ...

  2. NGUI List优化

    腾讯是如何做 Unity 手游性能优化的 https://juejin.im/entry/5774af485bbb50005925a3b1 Unity - NGUI - 优化ScrollView的一些 ...

  3. java控制流程(二)

    一.循环结构 有一天你的女朋友让你写一百遍我爱你,你是要一行一行的手写出来,还是利用编程的循环结构写出来? while 语法: 表达式返回的为boolean值 while(表达式){ 需要循环的语句 ...

  4. 索引对单表查询的影响(Cost和consistent gets)

    前提:使用system账户登录sql plus. 建表: SQL> create table t2 as select * from dba_objects; 表已创建. 已用时间: 00: 0 ...

  5. Oracle Sqlplus 三项设置

    显示sql执行时间:set timing on 显示sql execute plan:set autotrace trace exp  关闭 set autotrace off 设置行宽:set li ...

  6. IEDA使用Tomcat后控制台中文出现乱码

    如下图所示,Intellij IDEA显示中文为乱码, 根据Intellij IDEA控制台输出,Tomcat  Log出现乱码,因此可以将问题定位到Tomcat上,具体解决方法: 第一步:打开Tom ...

  7. pythont多线程

    import threading # 线程模块 def function(num): pass thread_1 = threading.Thread(target=function, args=(1 ...

  8. 虚拟机:主机能ping通虚拟机,虚拟机不可以ping通主机

    解决办法: 1.虚拟机可使用nat模式 2.虚拟机使用桥接模式,并且和主机再同一个ip段内 3.主机的防火墙关闭(不推荐使用,主机不安全) 4.主机中有个ICMPv4-In这个规则需要启用: 打开防火 ...

  9. 通过调用标识符确定this

    一. 纲 this的性质 作用:表示函数执行时的环境 值:一个对象 特点:动态性 确定this的难度 JS语言的动态性: 函数的this在执行时才能确定 函数为一级公民 可作实参.返回值.数据赋值进行 ...

  10. 执行./install.sh时报错-bash: ./install.sh: /bin/bash^M: 坏的解释器: 没有那个文件或目录

    百度解释说是因为这个文件在windows下编辑过,windows下每一行的结尾是\n\r, 而linux下每一行结尾是\n,所以只需要删除这个文件中的\r字符就可以了sed -i 's/\r$//' ...