AtCoder NoviStepsを埋めてみる(6) 再帰全探索 2Qまでの続きです。今回も再帰全探索です。

D – String Equivalence

D – String Equivalence

問題の概要

英小文字からなる 2 つの文字列 s, t の長さが同じであり、任意の i,j に対し次のいずれかが成立するとき同型 であると定義する。
s[i] = s[j] かつ t[i] = t[j]
s[i] ≠ s[j] かつ t[i] ≠ t[j]

文字列 s は以下の条件を満たすとき 標準形 であるといいます。
任意の s と同型な文字列 t に対し、s ≦ t (辞書順での比較)が成立する。
例)zyxzx の標準形は abcac

整数 N が与えられる。長さ N の標準形の文字列をすべて辞書順で出力せよ。

文字追加するとき、
文字列が空のときは ‘a’ を追加
それ以外のとき、’a’ から(文字列のなかにある辞書順でもっとも大きい文字の次の文字)までを追加する処理をすべて試す
をやればよいです。

072 – Loop Railway Plan(★4)

072 – Loop Railway Plan(★4)

問題の概要

H 行 W 列のグリッドがある、各マスは’,’のマスと’#’のマスのどちらかである。
ある’,’のマスを始点とし、始点と終点以外同じマスを通らず、上下左右で隣接する’,’のマスにのみ移動することを繰り返して始点に戻ってくる経路のなかで長さが最大の経路長を求めよ。

D – Dance

D – Dance

問題の概要

2N 人の人で N 組のペアをつくる。
i と j がペアになったときの「相性」は A[i, j] である。
相性のビットごとの排他的論理和を最大化したい。最大値を求めよ。

N の最大値は 8 なので全体で16人いることになります。長さ 16 の順列を全探索することは実行時間制限以内にはできないので他の方法を考えます。

N 個のペアにわけるとして各人が問題になるのはどのペアに属するかではなく、自分とペアになるのはどの人なのかということです。

ペアの最初の人はまだ相手が決まっていない人であれば誰を選んでもよいです。なのでまだ相手が決まっていない番号が一番小さい人を選びます。その人の相手は残りのなかから全探索します。この方法なら 8 ペアであればすべての組み合わせを全探索することができます。

D – Peaceful Teams

D – Peaceful Teams

問題の概要

N 人の選手がいて、そのなかで A[i] 番目の選手と B[i] 番目の選手は相性が悪い。
この選手たちを T 個のチームに分ける。
どの選手もちょうど一つのチームに属さなければならず、どのチームにも少なくとも一人の選手が属さなければならない。
また同じチームに相性が悪い選手同士がいてはならない。
この条件を満たすチーム分けの方法は何通りあるか求めよ。

各選手がどのチームに属するかを決めます。このときにD – String Equivalence にある標準形をつくったときのような処理をおこないます。標準形のなかで要素の種類が T 個ある場合、選手たちのチーム分けができたことになります。

あとは相性が悪い選手が同一チームでないチーム分けになっているものだけを数えます。

D – Domino Covering XOR

D – Domino Covering XOR

H 行 W 列のマス目があり、マス (i, j) には非負整数 A[i, j] が書かれている。
このマス目にドミノを 0 個以上置く。
1 つのドミノは隣り合う 2 つのマスを覆うように置くことができるが、同じマスに対して複数のドミノを置くことはできない。
ドミノが置かれていないマスに書かれた整数すべてのビットごとの排他的論理和を置き方のスコアと定義する。
ドミノの置き方のスコアとしてありうる最大値を求めよ。

ドミノは縦に置くか横に置くかのどちらかです。そこですべての(i, j)において、ドミノを (i, j), (i, j + 1) と置くか、(i, j), (i + 1, j) と置くか、置かないかを決めます。処理を高速にするためにはドミノを置く置かないを bit で管理するようにし、次のマスに移動するときは再帰呼び出しでドミノの状態を渡していきます。

D – Hanjo

D – Hanjo

問題の概要

H 行 W 列のグリッドと A 個の 1 × 2 の大きさのタイル、B 個の 1 × 1 の大きさのタイルがある。
グリッド上にタイルが重なったり隙間ができないように敷き詰めた場合、置き方は何通りあるだろうか?

D – Domino Covering XOR と同じような方法で解けますが、置き方を数え上げるときにダブルカウントしないように注意する必要があります。