AtCoder Beginner Contest 332 G問題メモ
G - Not Too Many Balls
問題
- N 色のボールがたくさんある。色 i=1,...,N のボールは Ai 個ある
- M 個の箱がある。箱 j=1,...,M にはボールを Bi 個まで入れられる
- 色 i のボールは、箱 j に i×j 個までしか入れられない
- 箱に入れられるボールの最大数を求めよ
- 1≤N≤500
- 1≤M≤5×105
- 0≤Ai,Bi≤1012
解法
M が十分に小さければ、最大流問題で解ける。
ボール 箱 ①--->① ボールと箱を結ぶ辺の容量は、頂点番号の積 A1↗ \\ / \B1 / \ × ↘ ⓢ X ②-B2-ⓣ \ / × ↗ A2↘ // \ /B3 ②--->③
でもさすがに M=5×105 は無理。
なので、ボール-箱間のコストが法則的なことを使わないといけない。
最大フロー最小カット定理 より、最小カットの考え方で解く。
最小カットは、以下で定義される。
- 全頂点を S,T グループに分ける
- 始点ⓢと終点ⓣはそれぞれ S,T 固定
- Sグループの頂点→Tグループの頂点 に張られた辺の容量の合計が「カット」
- S,T への分け方を上手く決めた場合のカットの最小値が「最小カット」
カットとなり得る辺を分類すると、以下のようになる。
分類 | 容量 |
---|---|
a) ⓢ-ボール間 | ボール頂点 i が T の時、Ai |
b) ボール-箱間 | ボール頂点 i が S、箱頂点 j が T の時、i×j |
c) 箱-ⓣ間 | 箱頂点 j が S の時、Bj |
a) b) c) ↓ ↓ ↓ ボール 箱 ● ● ○:Sに属する頂点 A1↗ ↗ ●:Tに属する頂点 / / ⓢ / ○-B2->ⓣ / / ○--->●
ここで、
- U:=1,2,...,N 全てのボール頂点からなる集合
- V:=1,2,...,M 全ての箱頂点からなる集合
- P:=S に属するボール頂点の集合
- ¯P:=T に属するボール頂点の集合
- Q:=S に属する箱頂点の集合
- f(A):= 頂点集合 A に属する頂点の、番号の総和
とする。
P,Q を固定した時のカットを式で表すと、以下になる。これを最小化したい。
- ∑i∈¯PAi+∑i∈P∑j∈¯Qi×j+∑j∈QBj …(1)
真ん中のb)を示す項 ∑i∈P∑j∈¯Qi×j は、 分配法則によってまとめて ∑j∈¯Qf(P)×j とできる。
すると、式(1)の3項のうち右2項は ∑j∈¯Qf(P)×j+∑j∈QBj となり、各 j は Q と ¯Q のどっちかには属するので、
- 頂点 j が Q に属するとき、Bj
- 頂点 j が Q に属しないとき、f(P)×j
結局、f(P) が決められたとき「各 j について Bj,f(P)j のどっちか小さい方を選べばよい」ということになる。
左の1項 ∑i∈¯PAi を考える。これも、上記と同じく f(P) を軸にまとめたい。
- g(t)=f(¯P) が t となるような ¯P における、∑i∈¯PAi の最小値
とすると、これは N×f(U)=O(N3) のDPで事前計算できる。
すると、f(¯P)=f(U)−f(P) なので、f(P) を決めると求めることができる。
f(P) を固定することでカットが計算できるようになったので、あとは実際に f(P)=k として k=0,1,...,f(U) を試す。
「k×j>Bj となるような j の集合」を Q として、
- g(f(U)−k)+k×f(¯Q)+∑j∈QBj
がカットとなり、全ての k を試した上での最小値が答え。
k が増加する毎に Q は増えていく一方なので、
f(¯Q) と ∑j∈QBj は、
はじめ Q=ϕ,¯Q=V からはじめて順次 Q に移していけばよい。
k=⌊Bjj⌋ であるような j を
k の処理が終わったタイミングで Q に移していけば、k を全て試す過程を通して O(M) で管理できる。
全体で O(N3+M)