AtCoder-ABC216 E - Amusement Park【Python解答例】
AtCoder Beginner Contest216のE問題についてPythonの解答例を記事にしていきます。
AtCoder Beginner Contest 216 - AtCoder
AtCoder Beginner Contest216 E - Amusement Park
問題文
髙橋君は遊園地に遊びに行きました。
この遊園地には N 個のアトラクションがあり、i 個目のアトラクションの「楽しさ」の初期値は A i です。
髙橋君が i 個目のアトラクションに乗ると、以下の現象が順番に起きます。
髙橋君の「満足度」に、i 個目のアトラクションの現在の「楽しさ」が加算される。
i 個目のアトラクションの「楽しさ」が、1 減少する。
髙橋君の「満足度」の初期値は 0 です。髙橋君はアトラクションに合計 K 回まで乗ることができます。
最終的な髙橋君の「満足度」の最大値はいくつですか?
なお、髙橋君の「満足度」はアトラクションに乗ること以外で変化しません。
制約
・1≤N≤10 ^5
・1≤K≤2×10 ^9
・1≤A i ≤2×10 ^9
・入力は全て整数
解答例
N, K = map(int,input().split()) A = list(map(int, input().split())) # 降順で最後の要素が0 A.sort(reverse=True) A.append(0) # 搭乗回数 k = 0 # 合計満足度 score = 0 # 搭乗回数が余るかどうか flag = True for i in range(N): # 次の要素と一致するまでに必要な搭乗回数 tmp = (i + 1) * (A[i] - A[i+1]) # tmpがKより大きければberak if k + tmp > K: break # スコアとkを更新 score += (i + 1) * (A[i]*(A[i]+1) - (A[i+1])*(A[i+1]+1)) // 2 k += tmp else: flag = False Kが0になるまでのスコア計算 if flag: div = (K-k) // (i+1) mod = (K-k) % (i+1) tmp = A[i] score += (i+1) * (tmp*(tmp+1) - (tmp-div)*(tmp-div+1))//2 score += mod * (tmp-div) print(score)
解説
乗るごとに満足度が1減るアトラクションがN個あり、K回搭乗できるときの満足度の最大値を答える問題です。
満足度のリストAは降順でソートしてから末尾に0を足します。
次のループで満足度の大きいアトラクションから搭乗回数kが制約のKを超えない範囲で乗り続けたときの満足度を貪欲に計算していきました。
i番目の要素からi+1番目の要素の満足度と一致するまで乗るとき、搭乗回数は(i + 1) * (A[i] - A[i+1])です。
満足度は1からA[i]までの和から、1からA[i+1]までの和を引いた値にi+1をかけた値です。
1からNまでの和についてはこちらを参照
ebisuke33.hatenablog.com
搭乗回数がKを超える場合は、ちょうどKになるまで満足度を足し合わせていきました。
最終的に求まったscoreを出力すればACでした。
ABC216の関連記事はこちら
ebisuke33.hatenablog.com
ebisuke33.hatenablog.com