大家好啊,我是贪心说的道理

前言

贪心问题初学的时候啥也不会,全都是感性理解的。

其实它是有道理可寻的。本篇研究如何有理有据的贪心。

说的道理

对于一类重点考虑选择顺序的问题,我们可以假设A在B前面比B在A前面更优,并分析关系。这个东西好像叫 exchange argument。

对于一些和二分图有关或者可以转化成二分图的问题,可以利用二分图相关的性质与定理有理有据的贪心。

下面是一些例题。这里的例子都比较简单,但是我想要强调的是考虑问题的方法,而不是问题本身有多难。

exchange argument

题1 典

有一个数列 \(a_{1...n}\),重新排列使得 \(\sum\limits_{i=1}^{n} ia_i\) 最大。

假设最优解中有两个位置 \(x,y\),不妨令 \(x<y\),那么如果交换 \(x,y\) 的位置,一定不会变优。(显然,毕竟是优解)

换句话说就是 \(xa_x+ya_y\ge ya_x+xa_y\)

\(x(a_x-a_y)\ge y(a_x-a_y)\)

\((a_x-a_y)(x-y)\ge 0\)

由于 \(x<y\),所以 \(a_x\le a_y\)

于是我们得到,最优解中,左边的数都比右边的数小。排个序就行了。这个就是排序不等式。

题2 [JSOI2007]建筑抢修

这题就是我说的那个题解上来就按xxx排序的

大家都知道这题的做法是按deadline排序然后反悔贪心,怎么来的?

设某个任务耗时是 \(a_i\),dealine 是 \(d_i\)。设 \(A(a_1,d_1), B(a_2,d_2)\)。不妨令 \(A\) 排在 \(B\) 的前面。假设交换位置后悔变劣,看看会怎么样。(注:我们是在一个决策序列中任意选了两个 \(A,B\),不一定相邻)

那既然换一下会变劣,肯定是原来 \(A,B\) 两个都可以,换一下之后排在后面的 \(A\) 不行了。

排在前面的 \(B\) 肯定是可以的,毕竟原来都可以,换到更前面显然还是可以的。

\(A\) 前面的耗时总共为 \(t_1\)\(A,B\) 之间的耗时总共为 \(t_2\)。(画图)可得:

  • \(t_1+a_1\le d_1\)\(t_1+a_1+t_2+a_2\le d_2\)
  • \(t_1+a_2\le d_2\)\(t_1+a_2+t_2+a_1>d_1\)

我们发现,同一个东西 \(t_1+a_1+t_2+a_2\),不严格比 \(d_2\) 小,严格比 \(d_1\) 大。那么 \(d_1<d_2\)

那我们就得出来了,我们要按 deadline 排序。

但是注意到这里还有一个能不能选的问题,排完序后不是扫一遍就可以的,还要再贪心一下。

对于一个任务,如果能选,不选肯定亏了,显然要选。如果不能选(时间超了),看看换掉前面的行不行。设前面选的最大的为 \(a_{mx}\),当前是 \(a_i\)。如果 \(a_{mx}>a_i\),那它就不该出现 —— 毕竟它让 \(a_i\) 不能做了,换掉它之后,\(a_i\) 再加上,总用时比原来还小,肯定还是合法的。不但没少完成,并且时间更少,更有利于后面继续完成。但是如果 \(a_{mx}\le a_i\),那说明换了之后也不会变优,甚至会变劣,肯定不换,直接不做了。

二分图

二分图上有各种有趣的性质。设左右点集为 \(A,B\),大小为 \(n,m\)

  • Hall 定理:设 \(G(S)\) 表示和集合 \(S\) 有边相连的点集。不妨令 \(n\le m\),则图有完美匹配当且仅当 \(\forall S\in A,|S|\le |G(S)|\)

必要性是显然的,如果有 \(|S|>|G(S)|\)\(S\) 中就会有一个点没匹配。

充分性:使用归纳法。对于当前的图,假设命题对于所有子图成立,证明命题对于当前的图成立。

假设存在一个 \(A\) 的真子集 \(T\) 使得 \(|T|=|G(T)|\),那么 \(A\) 中删掉 \(T\)\(B\) 中删掉 \(G(T)\),应该还是满足条件的。由归纳假设,\(T\) 存在一个完美匹配,\(A/T\) 也有完美匹配,而且使用的右部点不交,从而原图有完美匹配。

假如没有,那对于所有真子集,\(|T|<|G(T)|\)。任意从 \(S\) 中删去一条边(不删点),\(|G(T)|\) 顶多减少 \(1\)\(<\) 变成 \(\le\)。由归纳假设,删去这条边后的子图有完美匹配,而这个也是原图的完美匹配。

Hall 定理有一个扩展,就是图的最大匹配 \(=n-\max(|S|-|G(S)|)\)。比较容易感性理解,也很容易证明。

综上一定有完美匹配。

  • Gale-Ryser 定理:对于左右点数都为 \(n\) 的二分图,两个序列 \(a_i,b_i\) 可能是它的度数序列,当且仅当:首先它俩和相等,然后对 \(a_i\) 降序排序后,\(\forall k\in [1,n],\sum\limits_{i=1}^{k}a_i\le \sum\limits_{i=1}^{n}\min(b_i,k)\)

先说一下,如果没有和相等的条件,后面的不等式相当于右边点度数 \(\le b_i\),左边必须恰好是 \(a_i\),是否可以。

因此如果删去和相等,然后把后面的不等式对称一下,也是等价的。

下面是部分证明。必要性比充分性容易。wiki上说充分性不好证然后丢了一篇论文来,不想看了。这里感性理解充分性。

先说明必要性。

转化一下 \(\sum \min(b_i,k)\)。首先 \(\sum b_i\) 可以写成 \(\sum\limits_{i} i\times (\#j,b_j=i)\)。(\(\#\) 记号表示计数)

然后这个式子可以转化成 \(\sum\limits_{i} (\#j,b_j\ge i)\)。后面换成 \(\ge\) 就相当于求后缀和的和,它会把 \(i\) 位置算恰好 \(i\) 遍,就和上面的式子相同了。这个事情类似于 \(E(x)=\sum\limits_{i} P(x\ge i)\)

然后和 \(k\)\(\min\),就不能 \(>k\) 了,从而它就是 \(\sum\limits_{i=1}^{k} (\#j,b_j\ge i)\)。设 \(a'(i)\) 表示 \(b\)\(\ge i\) 的数量,它就是 \(a'(1...k)\) 的和。定理转化成: \(\forall k, \sum\limits_{i=1}^{k} a_i\le \sum\limits_{i=1}^{k} a'_i\)

然后我们把原问题转化成有一个 \(n\times n\)\(01\) 矩阵 \(A\) 表示二分图的邻接矩阵。那么 \(a_i,b_i\) 相当于行列和。我们设 \(a_i\) 为列和,\(b_i\) 为行和。

我们把每一行的 \(0\) 都放到最前面去,这样搞一遍之后发现 \(i\) 列的 \(0\) 的个数就是 \(a'(i)\)。而且这个操作不减少让列和的前缀和 (即,\(1...i\) 列的 \(1\) 个数)。从而 \(a\) 的每个前缀和一定都不超过 \(a'\) 的对应前缀和。这件事情是必要的。

接下来感性理解充分性。注意到上面 \(a'\) 是只和 \(b\) 有关的,\(a\) 可以随意排列而不影响 \(a'\)。从而我们其实是得到了 \(n!\) 组不等式。考虑取最严的那一组。不难发现当 \(a\) 降序时每个位置的前缀和都做到了最大,因此我们只需要让这时候的不等式满足就全都满足了,这个限制看起来限制的“很有劲”,所以它大概就是充分的。

题1 区间匹配贪心

有若干区间和若干个点,区间向区间中的点连边,求二分图最大匹配。

实际题目可参考 CF1718D Permutation for Burenka,那个题笛卡尔树一下之后就是这个贪心。

贪心策略是:对于每个点,取包含它的没被使用的区间中 \(r\) 最小的。或者说是按 \(r\) 排序后取区间中第一个没被使用的点。

考虑为啥这么干。这个等价于二分图匹配,区间连边。

考虑啥时候有完美匹配。对它做 Hall 定理,相当于:任选 \(n\) 个区间,\(n\le\) \(n\) 个区间的并区间中的点数。把区间并拆成若干段极长的连续区间,发现每段是独立的。从而可以转化成:对于任意 \([L,R]\)\([L,R]\) 中包含的区间数 \(\le [L,R]\) 中包含的点数。必须满足这个条件才能有完美匹配。

假设原来是满足这个条件的。取 \(r\) 最小的区间,取最左边的没匹配的点,发现这样做一定不会把后面满足的条件打破。因此如果有这个点直接把匹配连上就行了。如果匹配不了的话,根据Hall定理扩展,这也不会减少后面的匹配。

对于那个 CF 题,可以允许最多一次失配,稍微处理一下就行了。

题2 选物品贪心

比较典的题是:有 \(n\) 个物品,第 \(i\) 种有 \(a_i\) 个。每次要取恰好 \(k\) 种不同的物品各一个。问最多能取多少次。

上次去一个普及组模拟有这个题,考完了我才发现我只会 \(O(\sum a_i)\) 的做法,不会 \(O(n)\) 了。事实上和 \(n\) 相关的做法并没有那么容易。

它的策略是取 \(a_i\) 最大的 \(k\) 个物品。注意取完了要重新排一下序。根据这个可以写个暴力。

我们把它转化成 Gale-Ryser 定理的模型。相当于左边点度数是 \(a_i\),右边点度数是一堆 \(k\),补一下0把两边变相等的。然后左边点度数可以不用完。假设右边可以有 \(m\) 个点。

先把左边处理一下。设 \(c(i)\) 表示\(a\)\(\ge i\) 的数量。

从而我们要枚举右边然后 \(\le\) 左边。也就是 \(\forall i\le m,ki\le \sum\limits_{j=1}^{i} c(j)\)

求出第一个不满足的位置 \(-1\) 就是最大的 \(m\) 了。容易 \(O(n\log )\) 的搞。

题2ex CF1740F

考虑 \(M\) 中的元素。假设第 \(i\) 个是 \(x_i\),后面补 \(0\)。我们发现这个东西就相当于右部点的度数。

(最后得到的每个集合就是每个右部点连的左部点集合)

要使用 Gale-Ryser 定理,先把 \(a\) 处理一下。首先求一下 cnt 然后排序(原地进行),这个就是左部点度数。然后设 \(b_i\) 表示(操作后的)\(a\)\(\ge i\) 的个数。然后对 \(b\) 原地做一下前缀和。

我们要数 \(M\) 的种类数,而这个东西和 \(x_i\) 的排列顺序无关,因此只考虑 \(x\) 是降序的情况。需要满足:

  • \(x\) 降序
  • \(x\) 的和为 \(n\)
  • \(\forall i\)\(x\)\(i\) 个和 \(\le b_i\)

容易写出 dp。\(f(i,j,s)\) 表示确定了前 \(i\) 个,最后一个是 \(j\),和为 \(s\),方案数。这个状态需要满足 \(s\le b_i,ij\le s\)。考虑枚举上一个是 \(x\) (特殊处理 \(i=1\))。那么 \(j\le x,x\le s-j\)。从 \(f(i-1,x,s-j)\) 转移过来。

发现这个 \(x\) 一定是一段区间,因此对上一次的 \(f\) 求列前缀和就可以优化到 \(O(n^3)\)。然后滚动一下 \(i\),优化到 \(O(n^2)\) 空间,时间不变。

然后我们发现由于 \(j\) 是最后一个,结合降序, \(ij\le s\le n\)。从而 \((i,j)\) 的枚举量是 \(\sum n/i\),是调和级数。精细实现一下,复杂度优化到 \(O(n^2\log n)\)

posted @ 2021-05-05 11:29  Flandre-Zhu  阅读(275)  评论(3编辑  收藏  举报