Official

E - 展示ブースの配置 / Arrangement of Exhibition Booths Editorial by harurun4635 Editorial for printing


有名問題で、過去にもいくつか出題例があると思います。

以下 \(C\) は sort されているとします。


\(A\) を \(C\) の並べ替えとします。各 \(i\) について \(A_i\) と \(A_{i+1}\) がそれぞれどちらかが \(+\) の寄与、どちらかが \(-\) の寄与をします。

自明な条件として \(+\) が \(N-1\) 回、 \(-\) が \(N-1\) 回されます。そして、各 \(A_i\) について寄与の和は \(-2\) から \(2\) のいずれかの値をとり、奇数であるものは両端の \(2\) つで、それ以外の寄与の和は偶数です。 (☆)

直感的にはなるべく大きい値を \(+\) して、なるべく小さい値を \(-\) したいです。


以下、寄与を並べた列を \(B\) とします。求めたいものは \(S = \displaystyle \sum_{1 \le i \le N} B_i \times C_i\) の最大値です。

\(N\) が偶数のとき

☆を満たすような配列 \(B\) で、もっとも \(S\) が大きくなるものは

\[B = (-2, \dots, -2, -1, 1, 2, \dots, 2)\]

です。そして、この \(B\) が実際に実現可能であることも確かめられます。

\(N\) が奇数のとき

奇数の要素は \((1, 1)\) か \((-1, -1)\) のどちらかです。( \((1, -1)\) だと \(+\) の総和が偶数であることに矛盾します)

前者では

\[B = (-2, \dots, -2, 1, 1, 2 \dots , 2)\]

後者では

\[B = (-2, \dots, -2, -1, -1, 2 \dots , 2)\]

の時 \(S\) が最大になり( \(2, -2\) の個数はそれぞれ、総和が \(N-1\) になるようにします)、この \(B\) が実際に実現可能であることも確かめられます。

よって、これらの大きい方を答えとすればよいです。


補足

それぞれ、「 \(S\) が最大になる」のは、かなり自然な貪欲であるため、明らかだと思います。このような \(B\) が実際に実現可能であることも、奇数である項を両端に配置することに注意すれば、自然に構築できると思います。


実装例

n = int(input())
c = list(map(int, input().split()))
c.sort()

if n % 2 == 0:
    b = [-2] * (n//2-1) + [-1, 1] + [2] * (n//2-1)
    print(sum(x * y for x, y in zip(b, c)))
else:
    b1 = [-2] * (n//2) + [1, 1] + [2] * (n//2-1)
    b2 = [-2] * (n//2-1) + [-1, -1] + [2] * (n//2)
    a1 = sum(x * y for x, y in zip(b1, c))
    a2 = sum(x * y for x, y in zip(b2, c))
    print(max(a1, a2))

posted:
last update: