アルゴリズムと計算量の問題
を正の整数とする。文字列 からいくつかの文字を取り除き( 個でもよい)、残りの文字を順序を変えずに並べた文字列を の部分列という。 つの文字列の両方の部分列であるものを共通部分列といい、共通部分列のうち長さが最大のものを最長共通部分列という。
文字 からなる次の つの文字列を考える。
(, の長さはどちらも )
と の最長共通部分列は、文字列として何通りあるか。 の式で表せ(異なる位置から取り出しても同じ文字列になるものは 通りと数える)。
この問題で使うもの
この問題を解けるようになるまで(7 技能)
読み込み中…
右端(太枠)がこの問題で使う技能です。左へドラッグすると、さらに前の前提をさかのぼれます。技能を押すと、そこまでの道筋が光ります。
ヒント
行き詰まったら、上から順に 1 つずつ開いてください。
ヒント 1
まず の部分列がどんな形の文字列になるかを考えよう。共通部分列はその形のうち の部分列になるものである。
ヒント 2
の部分列は の形。 を のブロックに分けると、この形の文字列では次の文字のブロック内の位置が前の文字の位置以下なので、 文字ごとに真に後ろのブロックへ進まなければならない。
ヒント 3
最長共通部分列の長さは で、それは を満たす である。あとは組 の個数を数える。
答えと解説
答えを見る
どこでつまずきましたか?(選ぶと、戻る場所を案内します)
解説を読む
の部分列の形 は が 個、 が 個、 が 個の順に並んだ文字列なので、その部分列は
( を 個、 を 個、 を 個この順に並べた文字列)の形に限られ、この形の文字列はすべて の部分列である。したがって共通部分列は、この形の文字列のうち の部分列になるものである。
長さは 以下 を 文字ずつ区切った 番目の を第 ブロックとよぶ()。各ブロックの中では、 が 文字目、 が 文字目、 が 文字目にある。
を の部分列として取り出すとき、隣り合う 文字(前の文字・次の文字)の組は
のどれかである( は のときに現れる)。どの組でも、次の文字のブロック内の位置( なら , なら , なら )は、前の文字のブロック内の位置以下である。一方、部分列として取り出すには、次の文字を の中で前の文字より真に右から取らなければならない。もし 文字が同じブロックにあれば、次の文字はブロック内で前の文字より真に右、つまりブロック内の位置が真に大きくなければならず、上のことに反する。よって、次の文字は前の文字より真に後ろのブロックから取らなければならない。
したがって取り出す文字はすべて異なるブロックにあり、ブロックは 個なので
長さ は実現できる となる 以上の整数 に対し、第 〜 ブロックからは 、第 〜 ブロックからは 、第 〜 ブロックからは を 個ずつ取れば、 が の部分列として得られる。また なので の部分列でもある。
以上より、最長共通部分列の長さは であり、最長共通部分列は を満たす のすべてである。 が異なれば文字列も異なるので、その個数は を満たす 以上の整数の組 の個数、すなわち 種類から重複を許して 個選ぶ重複組合せの数
である。
(確認) のとき , で、最長共通部分列の長さは 、最長共通部分列は の 通り。式の値 と一致する。 のときは の 通りで、式の値 と一致する。
別解
の部分列は ()の形に限る。これが の部分列になる条件を調べる。
の第 ブロック()は a, b, c の順。 を最も左に取ると第 〜 ブロックの c を使う。次の b は、同じブロックの b は c より左にあるので使えず、第 ブロック以降から取る。よって は第 〜 ブロック。同様に直前の b の次の a は次のブロックの a なので、 は第 〜 ブロック。これが に収まる条件は (ある文字の個数が 0 のときも同じ式)。
したがって共通部分列の長さは高々 で、 になるのは のときで、そのとき必ず存在する(例: 全部 c など)。最長共通部分列は (, の整数)で、 が異なれば文字列も異なる。
個数は非負整数解の個数 。
検算: : , 、最長共通部分列は a, b, c の 3 通り。式は で一致。