ABC216 参加記録
コンテスト中AC:A, B, C, D
C - Many Balls
操作を逆順に考えるのは典型です。Nから始めて0にすることを考えると、魔法Aは-1、魔法Bは÷2することになります。
すると、奇数なら魔法Aしかできず、偶数なら魔法Bを使用する方が0に近づけます。
奇数ならA、偶数ならBを繰り返し、最後に操作列を逆順にすれば解が得られます。
提出コード:https://atcoder.jp/contests/abc216/submissions/25423537
D - Pair of Balls
実装がややこしかった問題。実装ミスでWAを量産しています。
集合を以下のように定義します。
: 筒の一番前に1つだけ存在する色の集合
: 筒の一番前に2つ存在する色の集合
色が先頭である場合、に色が存在しなければ、に挿入します。
そうでなければ、からを削除し、にを挿入します。これを挿入操作と呼ぶことにします。
初めに、全ての筒の先頭の色に挿入操作を行います。
そして、集合が空でない限りはペアが存在することになるので、以下の操作を繰り返します。
1. から色を1つ取り出す。
2. 色を先頭にもつ2つの筒から先頭のを取り除く
3. が空でなければ、現在先頭の色に挿入操作を行う
が空になった時、に色が残っていなければ、答えはYesです。そうでなければ、Noです。
集合の管理はC++ならsetを使えば検索、挿入、削除をlog時間で行えます。
を特定する操作は、挿入操作の時に各色について筒のインデックスを記録しておけばで得られます。
提出コード:https://atcoder.jp/contests/abc216/submissions/25437223
E - Amusement Park
コンテスト後に解説なしで解けました。コンテスト中は、K回以内で得られる満足度Xを二分探索する思考に陥っていました。
与えられた操作回数以内で最大化するような問題は二分探索を疑います。
今回の問題では、最適な取り方は大きいものから順番に取っていくことです。
例として、に操作した場合を示します。
重要部分を抜き出すと以下のように遷移します。
これは各要素を棒グラフとみなし、縦軸がとなるところで切断したような状況と同じです。なら、です。
では、操作回数回以内だと、どこまで小さい値で切断可能でしょうか。
操作回数はが大きくなるにつれて減少する、単調非減少(多分)な列なので、上記の問いに対して解を二分探索できます。
回以内の操作で切断できるかの判定は、が以上なら回の操作が必要で、そうでなければ0回なので、各についてこの総和をとることでで判定可能です。
が定まれば、まず、各について、〜までの満足度を取得できます。
もし操作可能回数が回残っていた場合、の時以外はは個より多く残っていることが保証されるので、追加での満足度を取得できます。(もしの個数が個以下ならで切断できます。)
なお、の時も実装上は同じにして問題ありません(入力例2のような場合)。
これが満足度の最大値となり、解を得られます。計算量はです。
提出コード:https://atcoder.jp/contests/abc216/submissions/25455746
F - Max Sum Counting
コンテスト後に解説なしで解けました。
全ての部分集合の和について、それぞれ何通りあるかを得るのは、部分和DPにより可能です。しかし、そこに最大値が何かを情報として持つことはできません。(部分和DPについての説明は省略します。ネット上に詳しいものがあると思います。)
ここで、をとる選択をしたときに、が最大値であるようにできれば、情報を持つ必要がなくなります。具体的にはが以下であれば、が必ず最大値となります。
上の状況を実現するため、の要素の値を基準として昇順ソートします。
全ての部分集合は要素の順番を入れ替えてもできるものは同じであるため、ソートすることに問題がなく、これも解法のヒントとなり得ると思います。
ソートされていると、をとる選択をした時に、の和がとなるのは、通りとなります。
よって、部分和DPでをとる選択をした時に、である場合のの総和をとっていけば答えが得られます。
補足ですが、を最大値にするためには、以降は全て取らない選択をする1通りしかないため、最大値がであるときの部分集合が何通りあるかは、までの選び方にのみ依存します。
提出コード:https://atcoder.jp/contests/abc216/submissions/25459401