大家好啊,我是贪心说的道理
前言
贪心问题初学的时候啥也不会,全都是感性理解的。
其实它是有道理可寻的。本篇研究如何有理有据的贪心。
说的道理
对于一类重点考虑选择顺序的问题,我们可以假设A在B前面比B在A前面更优,并分析关系。这个东西好像叫 exchange argument。
对于一些和二分图有关或者可以转化成二分图的问题,可以利用二分图相关的性质与定理有理有据的贪心。
下面是一些例题。这里的例子都比较简单,但是我想要强调的是考虑问题的方法,而不是问题本身有多难。
exchange argument
题1 典
有一个数列 ,重新排列使得 最大。
假设最优解中有两个位置 ,不妨令 ,那么如果交换 的位置,一定不会变优。(显然,毕竟是最优解)
换句话说就是
由于 ,所以 。
于是我们得到,最优解中,左边的数都比右边的数小。排个序就行了。这个就是排序不等式。
题2 [JSOI2007]建筑抢修
这题就是我说的那个题解上来就按xxx排序的
大家都知道这题的做法是按deadline排序然后反悔贪心,怎么来的?
设某个任务耗时是 ,dealine 是 。设 。不妨令 排在 的前面。假设交换位置后悔变劣,看看会怎么样。(注:我们是在一个决策序列中任意选了两个 ,不一定相邻)
那既然换一下会变劣,肯定是原来 两个都可以,换一下之后排在后面的 不行了。
排在前面的 肯定是可以的,毕竟原来都可以,换到更前面显然还是可以的。
设 前面的耗时总共为 , 之间的耗时总共为 。(画图)可得:
- ,
- ,
我们发现,同一个东西 ,不严格比 小,严格比 大。那么
那我们就得出来了,我们要按 deadline 排序。
但是注意到这里还有一个能不能选的问题,排完序后不是扫一遍就可以的,还要再贪心一下。
对于一个任务,如果能选,不选肯定亏了,显然要选。如果不能选(时间超了),看看换掉前面的行不行。设前面选的最大的为 ,当前是 。如果 ,那它就不该出现 —— 毕竟它让 不能做了,换掉它之后, 再加上,总用时比原来还小,肯定还是合法的。不但没少完成,并且时间更少,更有利于后面继续完成。但是如果 ,那说明换了之后也不会变优,甚至会变劣,肯定不换,直接不做了。
二分图
二分图上有各种有趣的性质。设左右点集为 ,大小为 。
- Hall 定理:设 表示和集合 有边相连的点集。不妨令 ,则图有完美匹配当且仅当
必要性是显然的,如果有 , 中就会有一个点没匹配。
充分性:使用归纳法。对于当前的图,假设命题对于所有子图成立,证明命题对于当前的图成立。
假设存在一个 的真子集 使得 ,那么 中删掉 , 中删掉 ,应该还是满足条件的。由归纳假设, 存在一个完美匹配, 也有完美匹配,而且使用的右部点不交,从而原图有完美匹配。
假如没有,那对于所有真子集,。任意从 中删去一条边(不删点), 顶多减少 , 变成 。由归纳假设,删去这条边后的子图有完美匹配,而这个也是原图的完美匹配。
Hall 定理有一个扩展,就是图的最大匹配 。比较容易感性理解,也很容易证明。
综上一定有完美匹配。
- Gale-Ryser 定理:对于左右点数都为 的二分图,两个序列 可能是它的度数序列,当且仅当:首先它俩和相等,然后对 降序排序后,
先说一下,如果没有和相等的条件,后面的不等式相当于右边点度数 ,左边必须恰好是 ,是否可以。
因此如果删去和相等,然后把后面的不等式对称一下,也是等价的。
下面是部分证明。必要性比充分性容易。wiki上说充分性不好证然后丢了一篇论文来,不想看了。这里感性理解充分性。
先说明必要性。
转化一下 。首先 可以写成 。( 记号表示计数)
然后这个式子可以转化成 。后面换成 就相当于求后缀和的和,它会把 位置算恰好 遍,就和上面的式子相同了。这个事情类似于 。
然后和 取 ,就不能 了,从而它就是 。设 表示 中 的数量,它就是 的和。定理转化成: 。
然后我们把原问题转化成有一个 的 矩阵 表示二分图的邻接矩阵。那么 相当于行列和。我们设 为列和, 为行和。
我们把每一行的 都放到最前面去,这样搞一遍之后发现 列的 的个数就是 。而且这个操作不减少让列和的前缀和 (即, 列的 个数)。从而 的每个前缀和一定都不超过 的对应前缀和。这件事情是必要的。
接下来感性理解充分性。注意到上面 是只和 有关的, 可以随意排列而不影响 。从而我们其实是得到了 组不等式。考虑取最严的那一组。不难发现当 降序时每个位置的前缀和都做到了最大,因此我们只需要让这时候的不等式满足就全都满足了,这个限制看起来限制的“很有劲”,所以它大概就是充分的。
题1 区间匹配贪心
有若干区间和若干个点,区间向区间中的点连边,求二分图最大匹配。
实际题目可参考 CF1718D Permutation for Burenka,那个题笛卡尔树一下之后就是这个贪心。
贪心策略是:对于每个点,取包含它的没被使用的区间中 最小的。或者说是按 排序后取区间中第一个没被使用的点。
考虑为啥这么干。这个等价于二分图匹配,区间连边。
考虑啥时候有完美匹配。对它做 Hall 定理,相当于:任选 个区间, 个区间的并区间中的点数。把区间并拆成若干段极长的连续区间,发现每段是独立的。从而可以转化成:对于任意 , 中包含的区间数 中包含的点数。必须满足这个条件才能有完美匹配。
假设原来是满足这个条件的。取 最小的区间,取最左边的没匹配的点,发现这样做一定不会把后面满足的条件打破。因此如果有这个点直接把匹配连上就行了。如果匹配不了的话,根据Hall定理扩展,这也不会减少后面的匹配。
对于那个 CF 题,可以允许最多一次失配,稍微处理一下就行了。
题2 选物品贪心
比较典的题是:有 个物品,第 种有 个。每次要取恰好 种不同的物品各一个。问最多能取多少次。
上次去一个普及组模拟有这个题,考完了我才发现我只会 的做法,不会 了。事实上和 相关的做法并没有那么容易。
它的策略是取 最大的 个物品。注意取完了要重新排一下序。根据这个可以写个暴力。
我们把它转化成 Gale-Ryser 定理的模型。相当于左边点度数是 ,右边点度数是一堆 ,补一下0把两边变相等的。然后左边点度数可以不用完。假设右边可以有 个点。
先把左边处理一下。设 表示 中 的数量。
从而我们要枚举右边然后 左边。也就是 。
求出第一个不满足的位置 就是最大的 了。容易 的搞。
题2ex CF1740F
考虑 中的元素。假设第 个是 ,后面补 。我们发现这个东西就相当于右部点的度数。
(最后得到的每个集合就是每个右部点连的左部点集合)
要使用 Gale-Ryser 定理,先把 处理一下。首先求一下 cnt 然后排序(原地进行),这个就是左部点度数。然后设 表示(操作后的) 中 的个数。然后对 原地做一下前缀和。
我们要数 的种类数,而这个东西和 的排列顺序无关,因此只考虑 是降序的情况。需要满足:
- 降序
- 的和为
- , 前 个和 。
容易写出 dp。 表示确定了前 个,最后一个是 ,和为 ,方案数。这个状态需要满足 。考虑枚举上一个是 (特殊处理 )。那么 。从 转移过来。
发现这个 一定是一段区间,因此对上一次的 求列前缀和就可以优化到 。然后滚动一下 ,优化到 空间,时间不变。
然后我们发现由于 是最后一个,结合降序, 。从而 的枚举量是 ,是调和级数。精细实现一下,复杂度优化到 。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效