AOJ 2585 - 一日乗車券
解法
- 1日乗り放題になる路線をビットで表したものがとなるようにする際の、1Dayパスポートの合計金額の最小値
をまず求めます。
これは、配るDPを用いて、を繰り返し計算していけばよいです。で求まります。
では、乗り放題の路線を決め打ちしてとした際の、からへ行く方法の中で、金額が最小になるものを調べます。
これは、
- 時間後ににいるような行き方のなかでの金額の最小値
とすると、グラフを拡張してダイクストラ法を使ってあげれば、が答えになります。
初期値は、です。
これを全ての状態について調べ、その最小値を求めれば答えが求まります。
感想
はじめ、が24以下であると勘違いして、間に合わないなぁ…って言ってました。状態が少し複雑になるだけでバグを埋め込みやすいので、バグ少なめでかけた点についてはよかったです。
ABC153 F - Silver Fox vs Monster
解法
について、で割り、切り上げをしておきます。これで、が
- 番目のモンスターを倒すまでにかかる攻撃回数
となります。加えて、全てのモンスターを、の昇順で並び替えます。
1番目のモンスターについて考えると、回どこかで攻撃しなければなりません。このモンスターへの攻撃を最適化することを考えると、の地点を攻撃することが最適です。なぜなら、これより右側の地点を攻撃してもを攻撃することはできず、これより左側の攻撃を攻撃をしても、1番目のモンスターよりも左側にモンスターは存在しないので、得をしません(右側にはモンスターがまだいる可能性があるので、できるだけ右側も攻撃できるようにするべきです)。
すると、の区間内に存在するモンスターは、回攻撃されることになります。
すると、1番目のモンスターを除去し、先ほどの区間内に存在するモンスターについて回攻撃を与えた後の状況について考えればよいことになります。
これを繰り返すと、前から順番に、番目のモンスターに攻撃すべき残り回数分だけ、で攻撃を行う、という操作を前から順番に繰り返せばよいです。
攻撃を行った回数のリストを作成します。範囲攻撃なので、ある区間について同じ値を足したいのですが、についての区間加算を、BIT上でいもす法のように、に値を加算、から値を引くことで表現します。
すると、今までで番目のモンスターに攻撃した回数が、BITにおける1からまでの値の総和を計算することで計算できるようになります。
また、を攻撃した際にダメージを与えられないモンスターのインデックスの最小値を計算するための変数を用意しておきます。初期値は左端のインデックスとしておきます。
今番目のモンスターについて処理を行う際、
攻撃した回数がを超えている場合
スルーします。超えていない場合
残り攻撃すべき回数をとします。
を計算します。しゃくとり法のようにをインクリメントしていき、を超える最小のを新たなとします。
すると、今回の処理でに回攻撃することになります。
答えにを加算します。
BITの処理は、の部分にを加算し、の部分からを減らします。
これを繰り返すことで、答えを求めることができます。
AOJ 2631 - Clique Coloring
解法
それぞれの頂点について、回目に選ばれたか選ばれてないか、について考えると、パターンあります。
これらをビットで表すと、だけ、全体から1つ頂点を減らすことができます。
また、回目と回目に同時に選ばれる頂点が2つ以上あることはありません。
つまり、2つ以上ビットが立っているパターンについては、そのような頂点があるか、ないかの2択になります。
2つ以上ビットが立っているパターンは、通り(1つもビットが立ってないのが1通り、1つのみビットが立っているのが通り)ありますが、この値をとして、通りのパターンについて枝刈り全探索をすればよいです。
が同時に立っているビットを既に選択したかどうか、次にどのパターンを選択するか、そして現在いくつの頂点を削減できたか、の情報を引数にもち、再帰でDFSをしました。
今見ているパターンを選択する場合は、引数にあるが同時に立っているビットの情報を更新(矛盾すればその場で打ち切り)、それぞれの立っているビットについて選ばれた回数を計算(を超えることはできません)し、再帰をします。
感想
数週間考えました…
このタイプは苦手です。
ABC152 F - Tree and Constraints
解法
あらかじめ、頂点からへのパスに使われる辺の集合を表すビット列を、前計算で計算しておきます。これは、任意の頂点からBFSで辿っていけば良いです。
個の条件からいくつか選んだ、条件の集合に対して以下のような数を計算します。
- 少なくともに含まれる条件を全て満たさないような辺の色の決め方の場合の数
すると、包除原理によって、に含まれる条件の個数が偶数なら求めた値を加算、奇数なら減算、を通りの全てのについて繰り返すと、求める答えとなります。
上で計算したかった値をとします。
に含まれる条件は全て満たさない、という仮定があるので、に含まれる条件に指定されている辺は全て白くしなければなりません。
逆に、それ以外の辺については何も制約がないので、黒白どちらでも問題ありません。
条件に指定されていない辺の個数をとすると、
となります。
あとはに対するが求まればよいです。
これは、に含まれる全ての条件について使われる辺を洗いだし、それらの和集合を求めれば、その個数をから引けばよいです。これは、最初に前計算しておいたビット列を用いると、OR演算を用いて簡単に計算することができます。
感想
問題を見た時点で包除っぽい、となってから、の制約に気づき、素直に考察が進んだと思います。