目次

第四回日本最強プログラマー学生選手権-予選-(AtCoder Beginner Contest 313)E,F問題メモ

第四回日本最強プログラマー学生選手権-予選-(AtCoder Beginner Contest 313)

ABCらしからぬ配点
100-300-400-550-600-625-625-650

E - Duplicate

E - Duplicate

問題

S = 313
1回目 (3を1回繰り返した文字列)+(1を3回繰り返した文字列)=3111
2回目 (3x1)+(1x1)+(1x1)=311
3回目 (3x1)+(1x1)=31
4回目 (3x1)=3

解法

変な法則なのでひとまず実験する。すると、適当な $S$ から始めるとほぼ永遠に終わらなくなる。

サンプルでは'1'はいっぱい増えても大丈夫そうなので、それ以外の小さい数で試すと、

22 → 22 → 22 → 22 → ...
23 → 222 → 2222 → 222222 → ...
32 → 33 → 333 → 333333 → ...

1212 → 11211 → 11121 → 11112 → 11111 → 1111 → 111 → 11 → 1
2121 → 2112 → 2111 → 211 → 21 → 2

1以外の数が2個続く箇所があるとアウト。(前後に何かしらくっついていたとしても、該当部分の変化は変わらない)

それ以外の場合はいけそう。
改めて、1以外が連続しない数で試してみると、以下が分かる。

S = 113111115111

113111115111
11113111111111511
1111113111111111111151
111111113111111111111111115
11111111113111111111111111111111
111111111111311111111111111111111
1111111111111131111111111111111111
11111111111111113111111111111111111
111111111111111111311111111111111111
(中略)
1111111111111111111111111111111111111111111111111131
11111111111111111111111111111111111111111111111111113
111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111
(中略)
111
11
1

なので、末尾から、1の連続はまとめてシミュレートすると解ける。

Python3

F - Flip Machines

F - Flip Machines

問題

解法

$X_j=Y_j$ か $X_j \neq Y_j$ かで、マシンを区別して考える。

$X_j=Y_j$ のマシンでは、カードを確実に裏返すことができる。

カード $i$ を $X_j \neq Y_j$ のマシンで裏返す候補にしたとき、期待値は平均値 $\dfrac{A_i+B_i}{2}$ となる。

その後、同様のことを何回行おうと、期待値は $\dfrac{A_i+B_i}{2}$ のままである。
その前後で $X_j=Y_j$ で裏返していても同様となる。

↗:裏返された  ↘or→:裏返されなかった

 1回目 2回目
        Ai
      ↗
    Bi→Bi
  ↗
Ai      Bi
  ↘  ↗
    Ai→Ai

        ↑何回分岐しようと、全ての確率は等しく、またAiとBiが同数現れる

よって、$M$ の制約は大きいが、同じペアのマシンを選ぶ必要は無いし、その順番も関係ないことが分かる。

問題の主旨は、各カードに対し、以下のいずれかを割り当てると言い換えられる。
$X_j=Y_j$ のマシンで裏返すことを「確実に裏返す」、$X_j \neq Y_j$ のマシンの対象とすることを「確率で裏返す」と表現する。

各カードは、マシンによって以下のように分類できる。

(A)と(D)の最適解はそれぞれ決定し、残る (B)(C) と (E) をどうするかという問題になる。

(B)(C)に含まれるカードの集合を $H$、(E)に含まれるのを $L$ とする。

$H$ のとある1枚の犠牲(③にする)で、複数の $L$ も③にして期待値を上げることができうるが、その組み合わせはどうすれば最適か?

それぞれに含まれるカードの数によって、2通りの解法がある。
$N \le 40$ なので、小さい方の集合サイズは多くとも $20$ であり、計算量 $2^{20}$ のアルゴリズムが間に合う。

$|H| \le |L|$ の場合

犠牲にする $H$ の部分集合を決めると、裏返す候補にできる $L$ の部分集合も決まる。

$H$ の部分集合を全探索して、最大値を取ればよい。

$|H| \gt |L|$ の場合

bitDPする。

最終的なDPの各 $S$ に、$S$ から計算できる $L$ 側の期待値も加算し、その中の最大値が答え。

いずれも、$O(N 2^{N/2})$ の計算量で解ける。

Python3