解説
解法
各オーディションごとに「必要ポイントを満たせるか」を判定する。
行動には 4 種類あるが、重要な観察として次が成り立つ:
- オールアピールを 3 回以上行う必要はない。
オールを T 回行った場合、T=3q+r (0≤r<3) と分解できる。
このとき
- オール r 回
- ダンス/ビジュアル/ボーカルをそれぞれ q 回ずつ
に置き換えると、加算ポイントはそれぞれ増え、総行動回数は T のままである。
よって「オールアピールを 0,1,2 回行う場合」だけを調べれば十分。
手順
- 各オーディション (Ai,Bi,Ci) について、オールを d=0,1,2 回行う場合を試す(ただし d≤K の範囲)。
- その場合に残る必要値を
Ai′=max(0,Ai−d⌊X/3⌋),Bi′=max(0,Bi−d⌊Y/3⌋),Ci′=max(0,Ci−d⌊Z/3⌋)
とする。
- 残りを単項目アピールで満たす最小回数は
needX=⎩⎨⎧0⌈XAi′⌉∞if Ai′≤0if X>0if X=0 and Ai′>0
(Y,Z も同様)。
切り上げは整数演算で (a + b - 1) // b と計算する。
- 総行動回数 d+needX+needY+needZ≤K なら、そのオーディションは合格可能。
以上を全オーディションについて判定し、合格できる数を数える。
正当性
- オールは 0,1,2 回しか調べなくてよい → 3 回以上は上位互換に置き換えられるため。
- 各項目は独立して考えられる。残りを埋めるのに最小限の単項目アピール回数を使えば最適。
- よって「d=0,1,2 を全探索 + 残りを貪欲に埋める」戦略で常に最適解を得られる。
計算量
- 各オーディションについて d=0,1,2 の最大 3 通りを試す。
- 1 通りごとの計算は定数時間。
- よって全体計算量は O(N)。
制約 N≤2×105 に対して十分高速。
コーナーケースと注意点
- 切り捨て/切り上げの誤差
- 浮動小数点を使うと誤差で
ceil がずれる可能性がある。必ず整数演算 (a + b - 1) // b で計算する。
- Pythonの場合切り捨ては
// を用いる (floor を用いない)。
- ゼロケース
A_i=0 ならその項目は行動不要。
X=0 かつ A_i=0 なら問題なし。
X=0 かつ A_i>0 なら不合格確定。
実装例は以下のようになります。