1 条题解
-
0
「USACO 2025 US Open Platinum」Package Pickup 题解
题目大意
Farmer John 在数轴上分布奶牛和包裹:
- 选定一个数字 ()
- 个奶牛区间 ,奶牛位于
- 个包裹区间 ,包裹位于
- 每秒可以移动一头奶牛一个单位距离
- 求捡起所有包裹的最短时间
解题思路
关键观察
-
模 分组:所有奶牛和包裹的位置都可以表示为 的形式,其中 。因此可以按余数 分组,每组独立处理。
-
问题转化:对于每个余数组,问题转化为在一条直线上有若干奶牛区间和包裹区间,求用最少的移动步数让所有包裹都被奶牛访问到。
-
区间合并:可以使用动态规划来合并区间信息,但直接合并复杂度太高,需要优化。
算法设计
状态设计
使用 的矩阵来表示状态转移代价:
- 状态 0:区间左端点在奶牛位置
- 状态 1:区间左端点在包裹位置
- 状态 2:区间右端点在奶牛位置
- 状态 3:区间右端点在包裹位置
矩阵 表示从状态 到状态 的最小代价。
矩阵合并
对于两个相邻的区间,它们的合并通过矩阵乘法实现:
- 基本矩阵
bd(z)表示间隔为 时的转移代价 - 区间信息通过
*运算符合并,考虑了区间间距的影响
数据结构优化
- 线段树:使用线段树维护每个余数组内的区间信息,支持快速插入、删除和查询
- 快速幂:对于跨块的区间合并,使用矩阵快速幂来加速
- 离散化处理:用
map记录关键点,分段处理
算法流程
- 输入处理:读入所有奶牛和包裹区间
- 按余数排序:将所有区间按 排序
- 建立关键点:用 map 记录所有区间的起点和终点对应的块编号
- 线段树维护:
- 插入区间时更新线段树
- 删除区间时清空对应节点
- 通过线段树合并区间信息
- 跨块合并:对于每个块区间,使用矩阵快速幂合并信息
- 答案提取:从最终矩阵的状态 2、3 到状态 0、1 中取最小值作为答案
复杂度分析
- 排序:
- 线段树操作:
- 矩阵乘法:,其中
- 总复杂度:,可以处理 的数据
代码实现要点
// 矩阵定义 struct Mat { ll f[4][4]; // 初始化为无穷大 }; // 基础转移矩阵 Mat bd(ll z) { // 根据间隔 z 构造转移矩阵 // 不同状态间的转移代价不同 } // 区间信息结构体 struct info { ll l, r; Mat f; // 合并运算符重载 };样例分析
样例 1:
M=100, 奶牛: [10,10], [20,20], [30,30] 包裹: [7,7], [11,11], [13,13], [17,17], [24,24], [26,26], [33,33]按余数分组后,在同一组内计算最小移动代价,最终得到 22。
样例 2:
M=2, 奶牛: [1,5], 包裹: [2,6]奶牛位置:1,3,5;包裹位置:2,4,6。最优方案需要 3 步。
总结
本题的难点在于:
- 发现模 分组的性质
- 设计合适的状态表示和转移矩阵
- 使用线段树和快速幂优化合并过程
通过将问题分解为独立余数组,并在每组内使用矩阵优化的动态规划,最终高效解决了这个看似复杂的问题。
标签:离散化、线段树、矩阵快速幂、动态规划、模运算分组
- 1
信息
- ID
- 4300
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者