均分纸牌详解
引入
每个位置的纸牌可以移向相邻位置,求使得所有位置纸牌数量相等所需的最小移动次数。
线形
呈一条直线,位置 \(1\) 只和位置 \(2\) 相邻,位置 \(n\) 只和位置 \(n-1\) 相邻,其余位置 \(i\) 和位置 \(i-1,i+1\) 相邻。
令 \(\overline s\) 表示平均数,\(a_i\) 表示位置 \(i\) 的纸牌数量。考虑所有位置 \(m\):
- 如果 \(\sum\limits_{i=1}^m a_i<m\times\overline s\),那么必然需要从 \(m+1\) 向 \(m\) 移 \(m\times\overline s-\sum\limits_{i=1}^m a_i\) 张纸牌。
- 如果 \(\sum\limits_{i=1}^m a_i>m\times\overline s\),那么必然需要从 \(m\) 向 \(m+1\) 移 \(\left(\sum\limits_{i=1}^m a_i\right)-m\times\overline s\) 张纸牌。
- 如果 \(\sum\limits_{i=1}^m a_i=m\times\overline s\),那么移动如果跨过 \(m\) 和 \(m+1\) 之间肯定不优。
除了必然需要的移动,我们发现剩下不需要任何移动了。
对于一次可以移动多张纸牌的情况,计算前两种情况的数量即可;对于一次只能移动一张纸牌的情况,计算前两种情况移动纸牌的总量即可。
环形
呈一个圆环,位置 \(1\) 和位置 \(n,2\) 相邻,位置 \(n\) 和位置 \(n-1,1\) 相邻,其余位置 \(i\) 和位置 \(i-1,i+1\) 相邻。
可以暴力枚举断点破环成链做到 \(O(n^2)\),证明考虑构造出一组存在至少一对相邻位置之间没有移动的最优解。
因为相邻两位置肯定只会单向移动,所以相邻位置之间都有移动的所有最优解一定是如下形式:
其中 \(x\) 表示间隔移动的纸牌数量,不妨设最小的为 \(x_1\)。
现在将 \(x_1\) 置为 \(0\),然后调整平衡。图中 \(x_2,x_3,x_7,x_9,x_{10}\) 均需增大原 \(x_1\),\(x_4,x_5,x_6,x_8\) 均需减小原 \(x_1\)。
这样保证不会出现负数,唯一的问题就是代价变大了。设增大的间隔有 \(l\) 个,那么减小的就有 \(n-l\) 个,如果 \(n-l<l\) 说明代价变大。
如果出现这种情况就换种调整方式,令 \(x_1\gets x_1\times 2\),这样仍能保证不出现负数,并且此时 \(n-l>l\),代价变小了,这与我们假设最优解的前提相矛盾。
所以第一种调整方式一定会使得代价不变。
对于一次可以移动多张纸牌的情况,在枚举的同时计算第三种情况的数量即可。
对于一次只能移动一张纸牌的情况就有点麻烦了
记 \(a\) 的前缀和数组为 \(pre\)
令 \(a_i\gets a_i-\overline s\)
因为 \(pre_n=0\),所以化简成
显然 \(pre_k\) 取中位数时最小。
二维
拓展到一个 \(n\times m\) 的二维矩阵,只需要保证每行的和都等于 \(\overline s\times m\),每一列的和都等于 \(\overline s\times n\)。
假设一行中相邻两位置发生了纸牌移动,那么对于所有行来说,其各自的和不变;假设一列中相邻两位置发生了纸牌移动,那么对于所有列来说,其各自的和不变。
也就是说每次移动会且仅会影响到一维,所以我们可以逐维进行调整,也就是对于每行和的数组和每列和的数组单独做一遍一维的情况。