はじめに
鳩が 匹と鳩の巣が
個あり、各鳩はいずれか一つの巣に入っているとします。このとき、
ならば、必ず
匹以上の鳩が入った巣が存在します。あたりまえ体操ですね。この主張を、鳩ノ巣原理と呼びます。
この鳩ノ巣原理、競プロでたまーに出てきては猛威を振るっていくんですが、本記事では昔出てきてちょっと感心した良問を紹介します。
問題概要
扱う問題はこれ ↓ です
問題概要
個の部署があり、各部署
には
人の社員が所属している。
人組のプロジェクトを作る。ここで、
- 一つのプロジェクトに同じ部署に所属する社員が
人以上参加してはならない。
- 一人が
つ以上のプロジェクトに参加してはならない。
- 一つのプロジェクトに同じ部署に所属する社員が
- 最大でいくつのプロジェクトを作ることができるか。
- 実行時間制限: 2sec
(人の社員を持つこの社、ヤバすぎる)
やりがちな嘘解法
単純な解法として、貪欲法が浮かびます。
例えば として、(必要ならソートをして)部署が人数の昇順に並んでいるとして、
- 部署
~
から
人ずつ取ってプロジェクトを作れるだけ作る。
- 部署
~
から
人ずつ取ってプロジェクトを作れるだけ作る。
- 部署
~
から
人ずつ取ってプロジェクトを作れるだけ作る。
- (以下繰り返し)
しかし、この解法は次のようなケースで最適解となりません。
(貪欲法だと 個しかプロジェクトが作れないですね。)
正しい解法
決め打ち二分探索
いつものです。
という判定問題を考え、
となる最大の
を二分探索します。
判定問題の解法
実は、任意の に対し次が成り立ちます:
\begin{equation} P(x) \Leftrightarrow \sum_{i=1}^{N} \min (A_i, x) \ge Kx \end{equation}
∵ 各部署について 人を超える分は無視してよいことに注意して(鳩ノ巣原理!)、各部署
の社員数を
とおきなおしたとき、
: 対偶を考えると、社員総数が足りていないので
は明らか。
: プロジェクトをそれぞれ
とする。部署順に社員全員を一列に並べて(同一部署の社員は自由な順で並べてok)前から順に
と番号をつけたとき、各社員
を
に参加させればよい*1。
提出コード
https://atcoder.jp/contests/abc227/submissions/64164861
おわりに
いかがでしたか?
鳩ノ巣原理には、しれっと出てきて「それはそう…」と落ち込ませる破壊力があります。つらい。
余談
鳩ノ巣原理を一般化したような立ち位置にある、Ramsey理論というものがあります。気になる人は組合せ論をやりましょう(布教)。
*1:この構成法は、問題概要の定義 2 つを両方とも満たしています。確認してみましょう。