現在、動的プログラミングの件名を開始し、教師の割り当てを掛けてきました
最長共通部分列と最長共通文字列は、古典的なタイトルDPです
具体的な問題は、オンラインで多くのバリエーションがあり、その後、私はほとんど元の質問をご紹介しましょう:
問題は、最長共通部分列の最も典型的なものです。これは、プロモーター配列とは異なり、次の点がサブストリングである:元の文字列内の文字の順序は、必ずしも連続的ではなく、サブストリングは、元の文字列の連続したサブセットであるが、文字の相対位置を変化させません。
私たちは、この2つの問題を解決するために、動的計画法を使用することができます。
1.最長共通サブシーケンス(LCS)
提供X = X1X2 ... XM及びY = Y1Y2 ... YN二つの配列、Z = z1z2 ... ZKである2つの配列の最長の共通のサブシーケンスです。
; 1 XM = YN、次いでZK = XM = YN、およびZK-1は、XM-1、YN-1最長共通サブシーケンスである場合
、Zは意味2. XM場合≠YN、次いでZK≠XM、 XM-1、Yの最長共通サブ;
3. XM場合は≠YN、次いでZK≠YN、Zは、最長共通サブシーケンスのX、YN-1であることを意味します。
私たちは、DPは、[i] [j]はビット文字列の最初のjビットの前に第二最長共通部分列Iの文字列を表現するために使用し、我々は簡単に見つけることができる場合、文字列の任意の二つの文字列現在の長さは最長共通サブシーケンスの長さがゼロであるので、第1の境界DPアレイが初期化され、ゼロです。その後、我々は[J-1] +1、明らかに、文字の場合、同じ組、缶よりも、その[I] = bの[J]であれば、DP [I] [J] = DP [I-1]が見つかり状態遷移の結果として得られる方程式。[I]≠B [j]は、DP [I] [J] = MAX(DP [I-1] [j]は、DP [I]、[J-1])場合、状態遷移方程式は、上記で2,3バーが得られた最大値をとります。
以下のコードを見てください:
1つの#include <ビット/ STDC ++ H> 2 使用して 名前空間STDを、 3 int型 DP [ 2005 ] [ 2005 ]。 4 INT メイン() 5 { 6 のchar [ 2005 ]、B [ 2005 ]。 7 CIN >> A >> B。 8 のために(int型 iは= 0 ; iは=のSTRLEN(A)<; iは++ ) 9 { 10 DPを[I] [ 0 ] = 0 ; 11 } 12 のために(INTJ = 0 ; J <= STRLEN(B); jは++ ) 13 { 14 DP [ 0 ] [j] = 0 ; 15 } 16 のための(int型 i = 1 ; iが<=のSTRLEN(A); iは++ ) 17 { 18 のための(int型 J = 1 ; J <= STRLEN(B); J ++ ) 19 { 20 であれば([I- 1を ] == B [J- 1 ]) 21 { 22 DP [I] [J] = DP [I- 1 ] [J- 1] + 1 。 23 } 24 他の 25 { 26 DP [I] [J] = MAX(DP [I- 1 ] [j]は、DP [I]、[J- 1 ])。 27 } 28 } 29 } 30 COUT << DP [strlenを(A)] [strlenを(B)] << ENDL。 31 リターン 0 ; 32 }
2.最長共通部分
これは、最長共通部分の基本的な概念であり、非常に多くの様配列が、文字列は、連続要求することです。私たちは、DPは、[i] [j]は最長共通部分で、第二の配列の前にiとjビット前のビットの文字列を表現するために使用し、我々は簡単に見つけることができる場合、文字列の任意の二つの文字列現在の長さは最長共通サブシーケンスの長さがゼロであるので、第1の境界DPアレイが初期化され、ゼロです。その後、我々は、その[I] = bの[Jもし見つかった [J-1] +1、]、DP [I] [J] = DP [I-1] 明らかに、文字の場合、同じ組、CANより状態遷移の結果として得られる方程式。[i]は[J B≠場合 DP [I] [J] = 0、]、 説明のか前には連続的なサブストリングを有していない、この不均等な位置に直接、破壊DPので[I] [J] = 0;
以下は、最長共通部分のコードです:
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 int型の DP [ 2005 ] [ 2005 ]; INT メイン() { char型 [ 2005 ]、B [ 2005 ]。 CIN >> A >> B; 以下のために(int型 i = 0 ; iが=のSTRLEN(A)<; iは++ ) { DPを[I] [ 0 ] = 0 ; } のための(INT J = 0 ; J <=のSTRLEN(B); J ++ ) { DP [ 0 ] [j] = 0; } のために(int型 i = 1 ; iは++; iが=のSTRLEN(A)< ) { ための(int型 J = 1 ; J <= STRLEN(B); jは++ ) { 場合([I- 1 ] == B [jで- 1 ]) { DP [i] [j]は DPを= [I- 1 ] [J- 1 ] + 1 。 } 他 { DP [I] [J] = 0 ; } } } COUT<< DP [STRLEN(A)] [strlenを(B)] << ENDL。 リターン 0 ; }