Codeforces Round #570 (Div. 3) F. Topforces Strikes Back
ちょっと変わった解き方をしたので記録。
(追記)公式Editorial もこの解き方でした。
問題概要
以下の問題を ケース解け。
- 個の正整数 が与えられる。この中から3個以下の整数を「どの2要素も約数・倍数の関係にない」という条件を満たすように選んだ時の、合計値の最大値を求めよ。
制約
- 各ケースについて、
- 全ケースの の合計は 以下
解法
「どの2要素も約数・倍数の関係にない」ことを単に「条件を満たす」と書くことにします。
同じ整数を2個以上選ぶことはできないので、とりあえず重複要素を除いておきます。以降は全要素が異なっているとします。
貪欲で行けないか?
以上の解法は通りそうになく、DPを組むのも難しそうなので、貪欲を疑ってみます。大きい方の要素から決められると嬉しいので、試しに「一番大きい要素を取ると決めてしまって良いだろうか?」「もしそれがダメなら、どのような反例が考えられるか?」を考えてみましょう。
これを証明するための常套手段は、
- 一番大きい要素を として、 以外から3個以下の要素を条件を満たすように選んだとき、ここから を選ぶように変更することで値を改善できる
ことを示すことです。
実際に、ほとんどの場合では値を改善できると示すことができます。選んだ要素の中に の約数が何個含まれるかで場合分けします。
の約数が0個の場合
この場合、どれか1個の要素を選ばないことにして代わりに を選ぶことで値が改善します。どれも の約数でないので条件に違反することはありません。
の約数が1, 2個の場合
この場合、 の約数であるものを選ばないことにして代わりに を選ぶと、条件に違反せずに必ず値が改善します。なぜなら の約数で でないものは のいずれかであり、この中から1個または2個を選んだ和は必ず よりも小さくなるからです。
の約数が3個の場合
同様に「 の約数を全部外して代わりに を選ぶと値が改善する」と言いたいところですが、3個ある場合は少しだけ事情が違います。3個の和が を超えるものが1パターンだけ存在し、それは の3個を選んでいる場合です。これは親切にサンプルにも含まれています。
これ以外に和が を超えるパターンがないことを示します。先ほどと同様に、 の約数で でないものは のいずれかであることを使います。
まず、3個全てが 以下だと和が を超えられないので、 は必ず含まれている必要があります。そうすると の約数となる は採用できません。
あと2個で残りの を超える必要があるので、同様の理由で が必ず含まれる必要があります。そうなると最後の1個はどちらの約数でもない から選ぶ必要があり、 であることから、最後の1個は しかありえません。
以上の考察を踏まえて
つまり、答えは以下の2通りのどちらかに絞られます。
- 最大要素 を使うと仮定したときに実現できる最大値。
- が全て含まれている時に限り、これら3個を選んだ合計値 。
最大要素を使うと仮定すれば、あとは の約数を全て消した上で、約数・倍数関係でない残り2個の合計を最大化する問題になります。これは先ほどの「 の約数が2個以下」のときの議論がそのまま使えて、やはり選べるものの中で最大のものを2個目として選ぶのが最適となります。さらに残ったものの中から3個目を選べば良いので、結局3個とも大きい方から貪欲で選べます。
が全て存在する場合は貪欲解と の大きい方を採用し、存在しない場合は貪欲解をそのまま答えとすれば良いです。ソートやset
の利用などを考慮して、ケースごとに計算量 で解けます。