题目大意
给定 $n$($n$ 是偶数,$2\le n\le 2\times 10^{5}$)个非负整数 $a_1,\dots, a_n$($a_i\le 10^9$)。
要求将其中 $n/2$ 个数变成平方数,另外 $n/2$ 个数变成非平方数,变化后的数必须仍是非负整数。
将 $x$ 变成 $x‘$ 的代价为 $|x-x‘|$ 。
求最小的总代价。
比赛时我的思路
用 $c_{i,0}$ 表示将 $a_i$ 变成平方数的最小代价,$c_{i,1}$ 表示将 $a_i$ 变成非平方数的最小代价,不难求出这两个值。
那么问题转化为
从 $c_{1,0}, c_{2,0}, \dots, c_{n,0}$ 和 $c_{1,1}, c_{2,1}, \dots, c_{n,1}$ 中各取出 $n/2$ 个数,限制条件是:$c_{i,0}$ 和 $c_{i,1}$ 不能都取。
求取出的数的最小和。
比赛时我想到这里就进展不下去了。
转化后的问题的解法
对于任意一个合法的取数方案,如果不是最优解,则必然存在 $i, j$ 满足:
- $c_{i,0}, c_{j,1}$ 在所取的数中,且
- $c_{i,0} + c_{j,1} > c_{i,1} + c_{j,0}$ 。
第二个条件可化为
$c_{i,1} - c_{i,0} < c_{j,1} - c_{j,0}$
这样便得出这个问题的解法:
将下标 $1, 2,\dots,i,\dots, n$ 按 $c_{i,1} - c_{i,0} $ 从小到大排序,对前 $n/2$ 个下标取 $c_{i,1}$,对后 $n/2$ 个下标取 $c_{i,0}$ 。
题解上解法
统计输入的 $n$ 个数中平方数和非平方数的个数,分别记做 $c_0, c_1$。
若 $c_0 = c_1$ 则无需改变。
若 $c_0 > c_1$ 则需要把 $(c_0 - c_1)/2$ 个平方数变成非平方数。对于非零的平方数,加 1 即可,零则须加 2 。所以,优先改变非零的平方数。
若 $c_0 < c_1$ 则需把 $(c_0 - c_1)/2 $ 个非平方数变成平方数。