No.794 チーム戦
概要
N 人(偶数)の人がいて、i 番目の人は整数 A_i を持っている。これらの人々を使ってペアを N / 2 組作りたい。ただし、各ペア(i, j)について A_i + A_j <= K が成り立っていないといけない。
そのようなペアの分け方は全部で何通りあるか?
制約
- , は偶数
考察
まず人の順番は無視していいので、は昇順にソートしておくことにする。すなわちが成り立っているものとする。
「2人の和がK以下」という制約が無ければ簡単で、答えは
となる。最後にで割らなければいけないことに注意する。なぜなら、例えば[1,2,3,4,5,6]とあるとき、({1,2}, {3,4}, {5,6}), ({1,2}, {5,6}, {3,4}), ({3,4}, {1,2}, {5,6})...のように同じ分け方でも順序が違うものを重複して数えてしまうからだ。
上の考察は無駄ではなくてKが十分大きいときはこの答えがそのまま使える。より厳密に言うと、であるとき上の答えに帰着される。
こういうのは相方の候補数が少ないもの、つまりが大きい順に考えてその候補数を掛け算していけばよさそうな感じがする。の相方の集合よりの相方の集合のほうが大きいので、がどれを相方にしても、の相方候補は1つ減るだけだから。(これを逆順にやってしまうとややこしくなってしまう……ということをABC114-Dで学んだ)
そうやりたいんだけど、問題はがをペアにした場合とかを考えると、次にを考えるのではなくを考えなければいけない、みたいになってかなりややこしくなってしまう。どうすればいいんだろう……?
よく考えるとがとペアになれるっていうことは、が成り立っているということで、これは上の「制約が無いパターン」に帰着されていることが分かる。すなわち、が成り立っているときは、前のi人は自由にペアを組めるのだ。
なので、がどこまで成り立つか?でグループ分けすると考えやすくなるのではないか、という考えが浮かぶ。すなわちを満たす最大のをmとして、前半組m人、後半組N - m人と分けてみよう。すると前半組のm人はどの2人を選んでもペアに出来るし、後半組のN-m人はどの2人を選んでも絶対にペアに出来ないことが分かる。ということは後半組は相方を前半組から取ってこなければいけない、ということも分かる。
ここまで来ると最初の懸念であった「がをペアにした場合とかを考えるとめんどくさい」という問題も解消されることが分かる。なぜなら後半組は絶対に前半組から相方を取ってくるので、後半組同士でペアになることは一切考えなくていいからだ。
これをアルゴリズムとして落とし込むと以下のようになる。
- ans = 1 とする
- 後半組の大きい順に、(以下を満たす人の数) - (既に処理した後半組の人の数) をansにかけていく
- 後半組が全て処理できたら、前半組で残ったm - (N - m) = 2m - N人は自由にペアに出来るので制約条件の無い問題に帰着して、それをansにかける
実際はans = 0になる場合とかがあるのでその場合は少し修正しなければいけないけど、だいたいこんな感じ
感想
解説と少し違ったやり方で解いたので書きましたが、kmjpさんのやり方とほぼ一緒ですね。少し違うのはkmjpさんはでグループ分けしてますね。確かにそっちのほうがシンプルだなあと思いました。