从Shopping Plans谈起的一类的经典 kth 问题
一类 kth 相关问题
实际上,这个 trick 以及其拓展在去年 noip 级别的模拟赛已经用到了多次,但是认知仅局限于“用优先队列”解决的一类题目,有时可以直接建立最短路模型。在去年一场 nfls 中甚至因为知道此 trick 而在最后一题狂砍 50 分,今天在 dmy 再遇,故整理其成体系。
T4 控制
有
类装备,每种类型有 种,且各有一个魔力值,定义一个方案为每一类选一个;你要求出前 大方案的魔力值总和。 套路题,优秀的暴力是 用优先队列维护,类似搜索,从一个状态向外转移,并加入堆里。为了避免加重,需要加入顺序的约定。
正解比较复杂,但发现本质和
很像,所以可以转换成图论,建立 个点,每个第 类的点,向每个第 类的点连边。直接可并堆优化 k 短路即可。需要虚拟源点和汇点。
0.模型与思路
给定你一个价值的计算方案,具体又可分为序列上子集和,子区间(超级钢琴),树上连通块。要求输出其第
这一类问题有通用思路:
对于目前考虑到的一个状态
- 取出堆顶
,计算 的答案。 - 将所有
放入堆里。
可以注意到,如果
1.Multiset
给定一个可重集
,求大小为 的第 小子集。
首先排序,最优一定是前
初始时
- 每次将最右侧的未移动点向右移动若干位,但不能跨越已移动点。
- 将其标记为已移动点。
容易发现,对于任何一个大小为
我们可以将转移抽象为树的形式,这样做的问题就在于,节点的儿子实在太多了。
但是只要保证解是逐渐变劣的,那么这棵树的形态是不重要的,那么我们可以用树的兄弟儿子表示法将树三度化,也就是说,每个节点只存它最优的儿子和向右第一个兄弟。
设四元组
表示最右侧的可移动点向右移动一格,也就是向右第一个兄弟。需要保证 。 表示将当前 向右移动一格。也就是最优的儿子。
不难发现,
例题:CF1250I。
2.Arrays
个数组,每个数组选一个数,求第 小和。
最小的肯定是每个数组选第一个数。套路的,每个数组内部升序排序,设
表示考虑到下一个数组。 表示考虑当前数组的下一个位置。- 初始为
。
但是这样会算重,很简单,你在
那当前数组想取第一个位置怎么办呢?我们只需在每个
。 。 。
但是注意:我们仍然要保证不断变劣(递增),而
细节:对于长度为 vector
里即可。
例题:P2541 [USACO16DEC] Robotic Cow Herd P。
与 k 短路的联系:不难发现本题可以直接图论建模,分层图求 k 短路,不过有些小题大做了。
3.Multisets(Shopping Plans)
有
个物品,每个物品有种类 和价格 。 对于第
个种类,购买个数必须在 的限制内。输出价格前 小的方案。
将两者结合起来。外层仍然是 Arrays 的做法,转移到当前数组的下一个位置
数组间是按照
说起来容易,实现起来或许非常困难。主要在于本题出人意料的特殊情况处理。
4.Tree
求树上第
小连通块点权和。
先考虑包含根的连通块,对有根树求出 dfs 序,建立一张新图:
表示选择 这个点。 表示跳过 的子树。
然后问题转换为 DAG k 短路。外面再套一层点分治,即可将无根转换为有根。复杂度
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现