【题目链接】

ybt 1593:【例 2】牧场的安排
洛谷 P1879 [USACO06NOV] Corn Fields G

【题目考点】

1. 状压动规

【解题思路】

集合状态:n个元素中,选择x个元素构成的集合,可以由一个n位二进制数表示。第i位为1表示选择第i个元素,第i位为0表示不选择第i个元素。
将在某格子种草称为为该格子着色。
本题每行着色的情况可以设为一个集合状态,称为着色状态。第i位为1表示选择了这一行的第i个格子已着色,第i位为0表示第i个格子没有着色。

sis_isi表示第i行的土地状态,sis_isi第j位为1表示第i行第j个格子可以着色,为0表示不可以着色。

二进制下的数字位,从0开始,从低位到高位分别是第0位,第1位。。。
例:二进制数:110 :第0位为0, 第1位为1,第2位为1

解法1:状压动规 枚举所有状态

状态定义
  • 阶段:前i行,第i行的着色为集合状态j
    第i+1行的集合状态受到第i行着色状态的影响,因此阶段之一需要是第i行的着色状态。
  • 决策:决定一行的着色
  • 策略:网格图的着色方案
  • 策略集合:对前i行着色,且第i行着色为集合状态j的所有着色方案
  • 统计量:方案数

状态定义dpi,jdp_{i,j}dpi,j:对前i行着色,且第i行着色为集合状态j的着色方案总数。

状态转移方程
  • 策略集合:对前i行着色,且第i行着色为集合状态j的所有着色方案
  • 分割策略集合:根据第i-1行的不同着色状态来分割策略集合

在求dpi,jdp_{i,j}dpi,j时,要枚举第i行的所有着色状态j,从中筛选出符要求的着色状态。在此过程中需要枚举第i-1行所有可能的着色状态,设枚举出的第i-1行的着色状态为k。

  1. 着色的格子必须是这一行可以着色的格子的子集

    因此第i行的着色状态j表示的已着色的格子必须是sis_isi表示的已着色的格子的子集,即必须满足s[i] & j == j
    第i-1行的着色状态k表示的已着色的格子必须是si−1s_{i-1}si1表示的已着色的格子的子集,即必须满足s[i-1] & k == k

  2. 每一行不可以有相邻的两个格子都着色。
    将k左移一位k<<1k<<1中第i位数为k中第i-1位数。k<<1的最低位为0。
    那么k<<1 & k的结果,就是将k的每一位与其右侧相邻一位进行按位与运算,(由于k<<1最低位为0,那么按位与的结果最低位为0)
    如果存在k的相邻两位都是1,那么结果不为0。如果不存在k的相邻两位都是1,那么结果为0。
    因此第i-1行只有满足(k<<1 & k) == 0(或写为!(k<<1 & k))的着色状态符合要求。同理第i行只有满足!(j << 1 & j)的着色状态符合要求。

  3. 第i行的着色状态j与第i-1行的着色状态k同一列的格子不能都着色。
    也就是这两个二进制数同一数位上不能都为1。
    如果k与j某一位都为1,那么k & j不为0,否则为0。
    因此k与j需要满足(k & j) == 0(或写为!(k & j)),才不存在第i行与第i-1行纵向上有相邻的格子都着色。

对于第i行的符合要求的着色状态j,找到一个符合要求的第i-1行的着色状态k,对前i-1行着色且第i-1行的着色状态为k的着色方案数为dpi−1,kdp_{i-1,k}dpi1,k
对i-1行所有满足条件的着色状态k,将dpi−1,kdp_{i-1,k}dpi1,k加和,即为对前i行着色且第i行着色状态为j的着色方案数。
因此dpi,j=∑dpi−1,kdp_{i,j} = \sum dp_{i-1,k}dpi,j=dpi1,k,j需要满足j & s[i] == j,k需要满足k & s[i-1] == k && !(k<<1 & k) && !(k & j)

对于初始状态,本题可以枚举第一行满足没有相邻格子染色(即满足j & s[1] == j && !(j<<1 & j))的染色状态j,第一行染色状态为j的方案有一种,设dp1,j=1dp_{1,j} = 1dp1,j=1

或者假设第0行参与染色,第0行只存在染色状态为0的一种情况,因此设dp0,0=1dp_{0,0}=1dp0,0=1

最后对于第m行的所有符合j & s[m] == j的状态j,求出为前m行染色,第m行着色状态为j的方案数,并加和。即结果为∑dpm,j\sum dp_{m,j}dpm,j,j满足j & s[m] == j

注意,每次加和后都要对10810^8108取模。

解法2:状压动规 保存合法的状态

本题每一行只会取没有相邻格子着色的状态,那么可以先将这些一定没有相邻格子同时着色的集合状态预处理出来,保存在state数组,state[i]表示第i个可用的集合状态。
而后dpi,jdp_{i,j}dpi,j表示的是对前i行着色,且第i行着色状态为state[j]的方案数。
接下来在判断着色状态是否符合要求时,就不用判断“要求相邻格子不能同时着色”这一点了,即不用再写j<<1 & jk<<1 & k

【题解代码】

解法1:状压动规 枚举所有状态
  • 写法1:设第1行的状态作为初始状态
#include<bits/stdc++.h>
using namespace std;
const int N = 12+5, S = (1<<12)+5, M = 1e8;
int m, n, s[N];//s[i]:第i行可以种草的集合状态 1表示可以种,0表示不可以种 
long long dp[N][S], ans;//dp[i][j]:前i行着色,第i行集合状态为j的方案数 
int main()
{int x;cin >> m >> n;for(int i = 1; i <= m; ++i)for(int j = 1; j <= n; ++j){cin >> x;s[i] = s[i]<<1 | x;}for(int j = 0; j < 1<<n; ++j) if((j & s[1]) == j && !(j & j<<1))//j不是s[i]的子集 或 j有相邻的着色格 dp[1][j] = 1;for(int i = 2; i <= m; ++i)for(int j = 0; j < 1<<n; ++j) if((j & s[i]) == j && !(j & j<<1))//j是s[i]的子集 同时 j没有相邻的着色格 for(int k = 0; k < 1<<n; ++k) if((k & s[i-1]) == k && !(k & k<<1) && !(k & j))//k不是s[i-1]的子集,或k有相邻着色格,或k与j有上下相邻的着色格 dp[i][j] = (dp[i][j]+dp[i-1][k])%M; for(int j = 0; j < 1<<n; ++j) if((j & s[m]) == j && !(j & j<<1))ans = (ans+dp[m][j])%M;cout << ans;return 0;
}
  • 写法2:设第0行的状态作为初始状态
#include<bits/stdc++.h>
using namespace std;
const int N = 12+5, S = (1<<12)+5, M = 1e8;
int m, n, s[N];//s[i]:第i行可以种草的集合状态 1表示可以种,0表示不可以种 
long long dp[N][S], ans;//dp[i][j]:前i行着色,第i行集合状态为j的方案数 
int main()
{int x;cin >> m >> n;for(int i = 1; i <= m; ++i)for(int j = 1; j <= n; ++j){cin >> x;s[i] = s[i]<<1 | x;}dp[0][0] = 1;for(int i = 1; i <= m; ++i)for(int j = 0; j < 1<<n; ++j) if((j & s[i]) == j && !(j & j<<1))//j是s[i]的子集 同时 j没有相邻的着色格 for(int k = 0; k < 1<<n; ++k) if((k & s[i-1]) == k && !(k & k<<1) && !(k & j))//k不是s[i-1]的子集,或k有相邻着色格,或k与j有上下相邻的着色格 dp[i][j] = (dp[i][j]+dp[i-1][k])%M; for(int j = 0; j < 1<<n; ++j) if((j & s[m]) == j && !(j & j<<1))ans = (ans+dp[m][j])%M;cout << ans;return 0;
}

解法2:状压动规 保存合法的状态

#include<bits/stdc++.h>
using namespace std;
const int N = 12+5, S = (1<<12)+5, M = 1e8;
int m, n, s[N];//s[i]:第i行可以种草的集合状态 1表示可以种,0表示不可以种 
int state[S], sn;//state[i]:第i个符合条件的集合状态 
long long dp[N][S], ans;//dp[i][j]:前i行着色,第i行集合状态为state[j]的方案数 
int main()
{int x;cin >> m >> n;for(int i = 1; i <= m; ++i)for(int j = 1; j <= n; ++j){cin >> x;s[i] = s[i]<<1 | x;}for(int i = 0; i < 1<<n; ++i) if((i & i<<1) == 0)state[++sn] = i;//把没有相邻的着色格的集合状态加入state for(int j = 1; j <= sn; ++j) if((state[j] & s[1]) == state[j])dp[1][j] = 1;for(int i = 2; i <= m; ++i)for(int j = 1; j <= sn; ++j) if((state[j] & s[i]) == state[j])//j不是s[i]的子集 for(int k = 1; k <= sn; ++k) if((state[k] & s[i-1]) == state[k] && !(state[k] & state[j]))//k不是s[i-1]的子集,或k有相邻着色格,或k与j有上下相邻的着色格 dp[i][j] = (dp[i][j]+dp[i-1][k])%M;for(int j = 1; j <= sn; ++j) if((state[j] & s[m]) == state[j])ans = (ans+dp[m][j])%M;cout << ans;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/90557.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/90557.shtml
英文地址,请注明出处:http://en.pswp.cn/web/90557.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot创建项目的方式

一、Idea Spring initializr创建&#xff08;Spring 官网下载&#xff09; Spring官网只支持SpringBoot3.0以上&#xff0c;JDK17以上 二、idea Spring inst创建&#xff08;阿里云下载&#xff09; 阿里云可以支持JDK8的版本 Spring版本选择2.7.6&#xff0c;选择合适的依赖添…

云原生 —— K8s 容器编排系统

一、 简介Kubernetes&#xff0c;也称为K8s&#xff0c;是一个开源的容器编排系统&#xff0c;用于自动部署、扩展和管理容器化应用程序&#xff0c;帮助开发者更高效地跨集群管理应用。本文总结了 k8s 的基础概念和技术架构。二、基础概念1. 云原生&#xff08;Cloud Native…

SQLite中SQL的解析执行:Lemon与VDBE的作用解析

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu) 在 SQLite 的内部实现中&#xff0c;SQL 语句的解析与执行是一个精妙的过程&#xff0c;涉及词法分析、语法分析、中间代码生成与执行等多个环节。其中&#xff0c;Lemon 工具和 VDBE&#xff08;Virtual Database Engine…

C++学习笔记(十:类与对象基础)

往篇内容&#xff1a; C学习笔记&#xff08;一&#xff09; 一、C编译阶段※ 二、入门案例解析 三、命名空间详解 四、C程序结构 C学习笔记&#xff08;二&#xff09; 五、函数基础 六、标识符 七、数据类型 补充&#xff1a;二进制相关的概念 sizeof 运算符简介 补…

图片查重从设计到实现(4)图片向量化存储-Milvus 单机版部署

Milvus 单机版部署 在 Docker 环境下安装、应用和配置 Milvus 向量数据库可以按照以下步骤进行&#xff0c;涵盖从安装到基础应用的完整流程&#xff1a; 1. 部署前准备 服务器&#xff1a;建议测试环境配置 2 核 CPU、8GB 内存&#xff1b;处理 100 万组向量数据&#xff0c;…

前端版本更新检测机制

&#x1f4cc; 一、为什么需要前端版本更新检测机制&#xff1f;在现代 Web 项目中&#xff0c;我们通常会通过 CDN 或缓存策略来加快页面加载速度&#xff0c;但这也带来了一个问题&#xff1a;用户可能访问的是旧版本的页面或资源&#xff0c;而不会自动更新到最新版本。这在…

Python(09)正则表达式

特殊字符 1. 基本元字符 .&#xff1a;匹配除换行符以外的任意单个字符。 *&#xff1a;匹配前面的元素零次或多次。 &#xff1a;匹配前面的元素一次或多次。 ?&#xff1a;匹配前面的元素零次或一次。 2. 定量符 {n}&#xff1a;匹配前面的元素恰好 n 次。 {n,}&#xff1a;…

k8s容器放开锁内存限制

参考&#xff1a;https://access.redhat.com/solutions/1257953 问题 nccl-test容器docker.io/library/nccl-tests:24.12中跑mpirun&#xff0c;buff设置为NCCL_BUFFSIZE503316480 提示out of memory&#xff1a; pod-1:78:91 [0] include/alloc.h:114 NCCL WARN Cuda failure …

基于Zigee的温度数据采集系统

大家好&#xff0c;本文带来的是单片机课设-基于Zigee的温度数据采集系统。 一、设计内容和要求 基于Zigbee的数据采集系统 1.1设计内容 &#xff08;1&#xff09;分析对比Bluetooth、Zigbee、Lora方式组网的基本原理和性能差异&#xff0c;撰写分析报告&#xff1b; &#xf…

ATH12K 驱动框架分析

文章目录 Linux Wireless 驱动框架深入分析 **1. 核心框架层次结构** **1.1 cfg80211 子系统 (`net/wireless/`)** **1.2 mac80211 子系统 (`net/mac80211/`)** **2. ath12k 驱动架构分析** **2.1 核心管理文件** **2.2 数据路径文件** **2.3 平台接口文件** **2.4 功能模块文件…

OSPF路由协议单区域

RIP的不足 以跳数评估的路由并非最优路径 如果RTA选择S0/0传输&#xff0c;传输需时会大大缩短为3sRIP协议限制网络直径不能超过16跳 收敛速度慢 RIP定期路由更新 – 更新计时器&#xff1a;定期路由更新的时间间隔&#xff0c;默认30秒。 – 失效计时器&#xff1a;失效计时器…

Kubernetes部署与管理Scrapy爬虫:企业级分布式爬虫平台构建指南

引言&#xff1a;Kubernetes在爬虫领域的战略价值在大规模数据采集场景中&#xff0c;​​容器化爬虫管理​​已成为企业级解决方案的核心。根据2023年爬虫技术调查报告&#xff1a;采用Kubernetes的爬虫系统平均资源利用率提升​​65%​​故障恢复时间从小时级缩短至​​秒级​…

Web-Machine-N7靶机攻略

一.环境准备&#xff08;VBox&#xff0c;kali虚拟机&#xff0c;靶机&#xff09; 1.1Vbox下载地址: Downloads – Oracle VirtualBox 1.2将N7导入到这个虚拟机中 1.3将kali和Vbox都设置成桥接模式 1.4开启靶机 若鼠标出不来可以使用组合技,CtrlAltDelete强制退出 二.信息…

用毫秒级视频回传打造稳定操控闭环之远程平衡控制系统技术实践

在工业自动化、远程机器人、无人装备等复杂作业场景中&#xff0c;远程实时操控正逐步取代传统“监控指令”模式&#xff0c;成为提升效率与保障安全的关键能力。尤其在高风险、高精度的应用环境中&#xff0c;操作者不仅要“能控”&#xff0c;更要“看得准、反应快”。 真正…

瑞萨电子RA-T MCU系列新成员RA2T1——电机控制专家

RA2T1系列微控制器基于64MHz ArmCortex-M23内核设计&#xff0c;专为单电机控制应用而优化。RA2T1集成PWM定时器&#xff0c;以及配备3个采样保持电路的A/D转换器等先进的模拟功能&#xff0c;适用于电动工具&#xff0c;风扇和家用电器等高效的低端电机控制方案。RA2T1支持1.6…

Java排序算法之<选择排序>

目录 1、选择排序 1.1、介绍 1.2、稳定性 2、执行流程 3、java实现 4、优缺点 总结&#xff1a;Java 排序算法进阶路线 O(n) 算法&#xff08;适合学习原理&#xff09; 冒泡排序&#xff08;最慢&#xff09;→ 选择排序 → 插入排序&#xff08;推荐先学&#xff09; …

ESP8266 http收发数据

1.先修改基础配置 make menuconfig 打开配置菜单 选择component config 然后选择 修改波特率为115200 保存退出 2.修改彩色日志打印的 在component config目录下找到log output 选中点击空格关掉彩色日志输出&#xff0c;这样正常串口打印就没有乱码了 然后保存退出 3…

ZLMediaKit 源代码入门

ZLMediaKit 是一个基于 C11 开发的高性能流媒体服务器框架&#xff0c;支持 RTSP、RTMP、HLS、HTTP-FLV 等协议。以下是源代码入门的详细指南&#xff1a; 1. 源码结构概览 主要目录结构&#xff1a; text ZLMediaKit/ ├── cmake/ # CMake 构建配置 ├── …

智能Agent场景实战指南 Day 21:Agent自主学习与改进机制

【智能Agent场景实战指南 Day 21】Agent自主学习与改进机制 文章内容 开篇 欢迎来到"智能Agent场景实战指南"系列的第21天&#xff01;今天我们将深入探讨智能Agent的自主学习与改进机制——这是使Agent能够持续提升性能、适应动态环境的核心能力。在真实业务场景…

微信小程序中英文切换miniprogram-i18n-plus

原生微信小程序使用 miniprogram-i18n-plus第一步&#xff1a;npm install miniprogram-i18n-plus -S安装完成后&#xff0c;会在项目文件文件夹 node_modules文件里生成 miniprogram-i18n-plus&#xff0c; 然后在工具栏-工具-构建npm&#xff0c;然后看到miniprogram_npm里面…