風船配り

問題文では 1 人の人が一度に三つずつ風船をとって子供たちに手渡していくことになっているが, 3 人の係(Aさん,Bさん,Cさんとしよう)がそれぞれポールの横に立って, タイミングを合わせて各自 1 個ずつ風船をとって子供に渡す風景を想像した方が考えやすいかもしれない.

ポールの並び順を一つ定めると,n 本のポールは A さんが手渡しを担当するポールと,B さん担当のポール,C さん担当のポールに分かれることになる. この時,担当ポールの風船の個数の和ができるだけ均等に近くなるよう, つまり,和が最小の係の風船の個数が最大になるようにすると, もっとも多くの子供が風船をもらえるのである.

つまりこの問題は結局, {b1, b2, ..., bn} を三つの集合 B1B2B3 に分割して, 和の最小値 min(ΣB1, ΣB2, ΣB3) が最大になるようにせよ,という問題になっている.そのような集合の分割が得られた時に, 実際にその分割に合わせてポールが 3 人の係に割り振られるように並べることは, 少し考えると必ず可能であるとわかる.

この整理された問題は Subset Sum Problem によく似ており,実際よく似た動的計画法で解くことができる.具体的には, dp[k][x][y] = "{b1, ..., bk} を 3 分割して和が (x, y, (Σki=1 bi)-x-y) となるようにできるか否か" という表を埋めればよい.