Official

F - Buy Balls Editorial by toam


はじめに,あらかじめ \(A,B\) をそれぞれ降順ソートしておきます.すると,価値の最大値は,数列 \(A\) の最初のいくつかの項と数列 \(B\) の最初のいくつかの項の合計になります.

\(\displaystyle S_i=\sum_{j=1}^i A_i, T_i=\sum_{j=1}^iB_j\) とおきます.ただし,\(S_0=0, T_0=0\) とします.求める答えは \(0\leq i\leq N, 0\leq j\leq M, j\leq i\) を満たすときの \(S_i+T_j\) の最大値です.すべての \(i,j\) に対して上の値を求めると計算量が \(O(NM)\) となり間に合いません.

\(i\) を固定したときの \(S_i+T_j\) の最大値を考えます.\(j\)\(0\leq j\leq \min(i,M)\) を満たす範囲を動くので,\(T_0,T_1,\ldots,T_{\min(i,M)}\) の最大値が分かればよいです.これは,あらかじめ \(T\) の累積 max を \(O(M)\) かけて前計算しておくことで,\(O(1)\) で求めることができます.

計算量はソートがボトルネックとなり \(O(N\log N + M\log M)\) です.

N, M = map(int, input().split())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
A.sort(reverse=True)
B.sort(reverse=True)
S, T, maxT = [0] * (N + 1), [0] * (M + 1), [0] * (M + 1)
for i in range(N):
    S[i + 1] = S[i] + A[i]
for i in range(M):
    T[i + 1] = T[i] + B[i]
    maxT[i + 1] = max(maxT[i], T[i + 1])

ans = 0
for i in range(N + 1):
    ans = max(ans, S[i] + maxT[min(i, M)])
print(ans)

posted:
last update: