当前位置: 首页 > news >正文

P1879 [USACO06NOV] Corn Fields G-提高+/省选-

P1879 [USACO06NOV] Corn Fields G

题目描述

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

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

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

输入格式

第一行:两个整数 MMMNNN,用空格隔开。

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

输出格式

一个整数,即牧场分配总方案数除以 10810^8108 的余数。

输入输出样例 #1

输入 #1

2 3
1 1 1
0 1 0

输出 #1

9

solution

用一个整数的二进制表示每一行种地的说有可能 (0 ~ 2^m - 1) 找到其中合法状态(没有连续的二进制位1),并找到所有的合法状态的相融状态 (没有任何位置同时存在1),找到每一行的土地状态 b(同样用二进制表示,1可以用,0不能用) 然后逐行递推即可

  • 1 定义公式
       j           : j 的二进制形式表示一种状态,即二进制为 1 的位该位置种,0 表示不种f[i][j]     : 第 i 行为 j 这种状态时,前 i 行种地的总方案数g[i]        : 第 i 行的土地状态a           : 所有合法一行状态的集合b           : b[j] 表示与 j 相适应的状态集合
  • 2 状态转移
      f[i + 1 & 1][k] += f[i & 1][j]);其中 k 是与 j 相适应且只在可用的土地上种地时的种地状态
  • 3 结果

    •  f[n + 1][0] 所有 n 行状态都可以转移到 0 这种状态
      
  • 4 初始状态

    •  f[0][0] = 1
      
  • 5 复杂度分析:

      时间复杂度:预处理 a, b : O(fib[m]^2)递推 :O(fib[m]^2*n)空间复杂度:省略一个维度后 O(2 * fib[m])

代码

#include <vector>
#include "iostream"
#include "algorithm"
#include "unordered_map"
#include "cstring"
#include "bit"using namespace std;/** P1879 [USACO06NOV] Corn Fields G* 题目大意:农场主 John 新买了一块长方形的新牧场,这块牧场被划分成 M 行 N 列 ,每一格都是一块正方形的土地。* John 打算在牧场上的某几格里种上美味的草,供他的奶牛们享用。遗憾的是,有些土地相当贫瘠,不能用来种草。并且,奶牛们喜欢独占一块草地的感觉,* 于是 John 不会选择两块相邻的土地,也就是说,没有哪两块草地有公共边。John 想知道,如果不考虑草地的总块数,那么,* 一共有多少种种植方案可供他选择?(当然,把新牧场完全荒废也是一种方案)** 数据范围:(1≤M≤12,1≤N≤12), 输出分配总方案数模 10^8** 思路:用一个整数的二进制表示每一行种地的说有可能 (0 ~ 2^m - 1) 找到其中合法状态(没有连续的二进制位1),并找到所有的合法状态的相融状态* (没有任何位置同时存在1),找到每一行的土地状态 b(同样用二进制表示,1可以用,0不能用) 然后逐行递推即可** 1 定义公式*      j           : j 的二进制形式表示一种状态,即二进制为 1 的位该位置种,0 表示不种*      f[i][j]     : 第 i 行为 j 这种状态时,前 i 行种地的总方案数*      g[i]        : 第 i 行的土地状态*      a           : 所有合法一行状态的集合*      b           : b[j] 表示与 j 相适应的状态集合* 2 状态转移*      f[i + 1 & 1][k] += f[i & 1][j]);*      其中 k 是与 j 相适应且只在可用的土地上种地时的种地状态* 3 结果*      f[n + 1][0] 所有 n 行状态都可以转移到 0 这种状态* 4 初始状态*      f[0][0] = 1** 5 复杂度分析:*      时间复杂度:*          预处理 a, b : O(fib[m]^2)*          递推 :O(fib[m]^2*n)*      空间复杂度:*          省略一个维度后 O(2 * fib[m])*/typedef long long ll;const int N = 1e5 + 5, M = 1e8;int n, m, s, g[13], f[2][(1 << 12) + 5];vector<int> a;
vector<vector<int>> b;int main() {cin >> n >> m;for (int i = 1; i <= n; i++)for (int j = 0, x; j < m; j++) cin >> x, g[i] |= x << j;for (int i = 0; i < (1 << m); i++) if (!(i & (i << 1))) a.push_back(i);s = int(a.size());for (int i = 0; i < s; i++) {b.emplace_back();for (int j = 0; j < s; j++) if (!(a[i] & a[j])) b[i].push_back(j);}f[0][0] = 1;for (int i = 0; i <= n; i++) {for (int j = 0; j < s; j++) {for (int k: b[j]) if ((a[k] & g[i + 1]) == a[k])f[i + 1 & 1][k] = (f[i + 1 & 1][k] + f[i & 1][j]) % M;f[i & 1][j] = 0;}}cout << f[n + 1 & 1][0] << endl;return 0;
}

结果

在这里插入图片描述

http://www.dtcms.com/a/393229.html

相关文章:

  • 二分答案:跳石头
  • 注解学习,简单测试框架
  • python 自定义装饰器 + 框架
  • 【星闪】Hi2821 | KEYSCAN矩阵按键扫描
  • ​​[硬件电路-282]:PWM信号通用解读、应用场景及在步进电机中的应用详解
  • 给链表装上“后视镜”:深入理解双向链表的自由与高效
  • Off-Grid Direction of Arrival Estimation Using Sparse Bayesian Inference (II)
  • Unity中的渲染管线
  • PyMuPDF 库
  • 【故障】windows7开机后能出现windows启动界面,但停在黑屏很久才进入系统界面
  • tqdm 库
  • 模块化编程规范与分层设计指南
  • Photoshop - Photoshop 调整照片的颜色强度
  • 【ROS2】通讯机制 Topic 常用命令行
  • DeepSeek的GPU优化秘籍:解锁大规模AI训练的底层效率
  • Gemini in Chrome深度解析:反垄断胜诉后,Chrome开启AI智能浏览时代!
  • 如何修复 Google Chrome 上的白屏问题
  • Camera2原生api级 Demo答
  • 【Redis】Redis缓存与数据库DB数据如何保持同步?
  • 考研408---C语言复习
  • 批量抓取图片
  • WinDivert学习文档之五-————编程API(十一)
  • 【打印菱形】
  • XC7Z100-2FFG900I Xilinx AMD Zynq-7000 FPGA SoC
  • 成本价的SEO优化服务供应链
  • dock生命周期体验-生到死的命令
  • 软件测试方案-模板一
  • 防火墙WEB方式登录配置【HCL模拟】-学习篇(1)
  • Ceph用户管理与cephFS分布式存储实战
  • AgenticSeek:重新定义AI助手的边界 - 100%本地化智能代理系统深度解析