T3
sol1 70pts
直接爆搜/二进制枚举即可。
sol2 100pts
设\(sum\)为所有数字之和。
注意到当\(n=36\)时,\(2^n\)太大了。
但是\(2^{\left \lfloor \frac{n}{2} \right \rfloor}\)是完全可以的。
在这个方法中;
原题是:选出\(\left \lfloor \frac{n}{2} \right \rfloor\)个,使选的数的和和没选的数的和的差的绝对值最小。
我们改成是:选出\(\left \lfloor \frac{n}{2} \right \rfloor\)或\(\left \lfloor \frac{n + 1}{2} \right \rfloor\)个,且满足选的数字之和不大于没选的数字和(即选的数的和\(\leq \frac{sum}{2}\))
那么我们可以先爆搜前\(\left \lfloor \frac{n}{2} \right \rfloor\)位,一共大概\(2\times 10^5\)种可能性
因为选出的人数也有要求,所以将前半部分的所有情况按照选的个数区分。区分出\(\left \lfloor \frac{n}{2} \right \rfloor + 1\)个集合,集合\(x\)存储的是前半部分中选出\(x\)个可以达到的所有的数字和。
然后爆搜后\(n - \left \lfloor \frac{n}{2} \right \rfloor\)位,对于每种方法,设\(s\)表示这个后半部分的方法的选出的数字之和,然后分成选\(\left \lfloor \frac{n}{2} \right \rfloor\)个和选\(\left \lfloor \frac{n+1}{2} \right \rfloor\)个两种情况,分别求出前半部分还需要多少个,然后在对应的集合里面二分出最大的数,满足加上\(s\)后\(\leq \frac{sum}{2}\),也就是说在满足与后半部分相加仍\(\leq \frac{sum}{2}\)的情况下前半部分的数字和最大可以是多少。(选的数字的和比没选的数字的和少的情况下,选的数字之和越大,选的数字之和和没选的数字之和的差越小)最后再用这个最大的数字与\(s\)相加,得到选出的数字和,再和\(sum\)做差求出没选的数字和,最后选出和没选出的做差得到这个后半部分方案的最小答案。
本题的答案就是所有后半部分方案的答案的最小值。
代码:
// 请自行尝试实现,代码暂不开放。
sol3 100pts
设\(sum\)为所有数字之和。
注意到当\(n=36\)时,\(2^n\)太大了。
但是\(2^{\left \lfloor \frac{n}{2} \right \rfloor}\)是完全可以的。
设\(m = \left \lfloor \frac{n}{2} \right \rfloor\)
那么我们可以先爆搜前\(m\)位,一共大概\(2\times 10^5\)种可能性
因为选出的人数也有要求,所以将前半部分的所有情况按照选的个数区分。区分出\(m + 1\)个集合,集合\(x\)存储的是前半部分中选出\(x\)个可以达到的所有的数字和。
然后爆搜后\(n - m\)位,对于每种方法,设\(s\),\(c\)分别表示这个后半部分的方法的选出数字之和及数字个数。
- 如果\(c > m\)说明选的个数已经超过了题目要求,直接跳过;
- 如果\(c = m\)说明已经选满了\(\left \lfloor \frac{n}{2} \right \rfloor\)个,直接根据\(s\)和\(sum\)求出这个后半部分的方案的答案。
- 如果\(c < m\)说明前半部分还要选\(m - c\)个,而且前半部分的数字总和需要尽可能接近\(\frac{sum}{2} - s\),这样加上\(s\)就更接近\(sum\)的一半。而接近\(\frac{sum}{2} - s\)分为比它大和比它小,所以再前半部分的集合\(m-c\)中二分出大于\(\frac{sum}{2} - s\)的最小值和小于\(\frac{sum}{2} - s\)的最大值,比较一下这两种方法算出的答案哪个较小,即为这个后半部分的方案的答案。
最后求出所有后半部分的方案的答案中最小的答案是哪个,将其输出即可。
代码:
// 请自行尝试实现,代码暂不开放。

浙公网安备 33010602011771号