差分
このページの2つのバージョン間の差分を表示します。
両方とも前のリビジョン前のリビジョン | 次のリビジョン両方とも次のリビジョン | ||
programming_algorithm:dynamic_programming:longest_common_subsequence [2019/01/09] – ikatakos | programming_algorithm:dynamic_programming:longest_common_subsequence [2019/01/09] – ikatakos | ||
---|---|---|---|
行 122: | 行 122: | ||
* [[wp> | * [[wp> | ||
- | |S|×|T| の配列上でDPを行い、途中の計算結果を保存しておくことで、最長共通部分列と共に、その具体例を構築することが出来る。 | + | $(|S|+1) \times |
+ | |||
+ | ===DPテーブルの構築=== | ||
S1...i と T1...j のLCSの長さを Li,j とする。 | S1...i と T1...j のLCSの長さを Li,j とする。 | ||
+ | |||
+ | L0,j=0,Li,0=0 とする。 | ||
==Si+1=Tj+1 の時== | ==Si+1=Tj+1 の時== | ||
行 134: | 行 138: | ||
LCS長は、片方の末尾を1文字削った2通りの長い方となる。 Li+1,j+1=max(Li+1,j,Li,j+1) | LCS長は、片方の末尾を1文字削った2通りの長い方となる。 Li+1,j+1=max(Li+1,j,Li,j+1) | ||
- | これで、i=1..|S|、j=1..|T| の2重ループでDPテーブルを小さい方から埋めていくことで、$DP[|S|][|T|]$ が最終的なLCS長となる。 | + | これで、i=1..|S|、j=1..|T| の2重ループでDPテーブルを小さい方から埋めていくことで、$L_{|S|,|T|}$ が最終的なLCS長となる。 |
+ | |||
+ | ===具体例の構築=== | ||
- | で、具体的な文字列は、$DP[|S|][|T|]$ | + | 具体的な文字列は、DPテーブルから逆向きに復元する。(i,j)=(|S|,|T|) とする。 |
- | ==$DP[i][j]=DP[i][j-1]またはDP[i][j]=DP[i-1][j]$ の時== | + | ==$L_{i,j}=L_{i,j-1}またはL_{i,j}=L_{i-1,j}$ の時== |
- | 同じである数字の方に移動する。両方同じ場合は、具体例が1つ構築できればいい場合は適当に1つ選んで移動する。 | + | 同じである数字の方に(i,j)を移動する。両方同じ場合は、具体例が1つ構築できればいい場合は適当に1つ選んで移動する。 |
==それ以外の時== | ==それ以外の時== |