Brick
Brick
题目描述
有 \(n\) 堆砖,首尾相连构成一个环,每次可以将相邻两堆砖同时加或减一,最后要求使用最少操作次数的情况下将所有砖堆变为尽量小的同一高度。
如果无法达到同一高度,则无解。
解题思路
设 \(x_i\) 表示同时修改 \(a_i\),\(a_{i+1}\) 的量(带正负),\(L\) 表示最终高度。
可以列出方程:
操作次数为 \(\sum |x|\)。
当 \(n\) 为奇数时:
把每一条方程加起来:
得出 \(2 \times \sum x = nL + \sum a\) 。
\(L\) 可以随便取值,与 \(\sum a\) 奇偶性相同即可有解。
所以可以先取定 \(L\) 为 \(0\) 或 \(1\)。然后将奇数位除最后一条式子全部相加得到 \(\sum_{i\in[1,n)} x\) 求出 \(x_n\),推到出所有的 \(x\)。
考察 \(L\) 变为 \(L + 2D\) 对于 \(x\) 的影响。
其可以使得所有的 \(x\) 变成 \(x + D\),即可以任意平移。
根据经典结论,我们只需要将中位数移到 x轴
上即可使得 \(\sum |x|\) 最小。
\(D = -x_mid\),即可求出 \(L\)。
当 \(n\) 为偶数时:
将奇数位的式子相加得到 \(\sum x = (n / 2) L + \sum_{i = 2k+1} a_i\),将偶数位式子也相加得到 \(\sum x = (n / 2) L + \sum_{i = 2k} a_i\)。
所以如果 \(\sum_{i=2k+1} a_i = \sum_{i=2k}\) 那么方程有解,否则无解。
先定 \(L\) 为 \(0\)。
考察 \(L\) 变为 \(L + 2D\) 对于 \(x\) 的影响。其与 \(n\) 为奇数的情况相同。
考察 \(x_1\) 变为 \(x_1 + Y\) 对于 \(x\) 的影响。
其会使得 \(x_{i \in 2k+1}\) 变为 \(x_{i \in 2k+1} + Y\),\(x_{i \in 2k}\) 变为 \(x_{i \in 2k} - Y\)。
总的来说通过调整 \(D\) 与 \(Y\),我们会使得 \(x\) 发生一下变化。
- 使 \(x_{i \in 2k+1}\) 变为 \(x_{i \in 2k+1} + D + Y\)。
- 使 \(x_{i \in 2k}\) 变为 \(x_{i \in 2k} + D - Y\)。
设 \(D + Y = A\),\(D - Y = B\)。
显然 \(A\) 与 \(B\) 可以取任意值。
所以我们只要将这两组 \(x\) 的中位数移动到 x轴
上即可。
即 \(A = -x_1[mid]\),\(B = -x_2[mid]\)。
解出 \(D\),\(Y\) 即可求出答案。
代码实现
我们可以使用 nth_element
在 \(O(logn)\) 的时间内找到中位数(此函数不止此功能),所以总的时间复杂度为 \(O(n)\)。
使用 namespace
之类的可以有效分离两种情况,避免变量冲突。