エヴァは、与えられた1のうち、自分のカラーストライプを作成しようとしています。彼女は、これらの不要な部分をカットし、彼女の好きな色のストライプを形成するために一緒に残りの部分を縫製し、彼女の好きな順序でのみ、彼女の好きな色を維持したいと思います。
エヴァの好きな色が限られているので、通常の人間の目は、200未満の異なる色について区別できると言われています。しかし、元のストライプは非常に長くなる可能性があり、そしてエヴァは、最大長さの残りの好きなストライプを持っていると思います。そこで彼女は彼女に最高の結果を見つけるためにあなたの助けを必要とします。
ソリューションは一意ではないかもしれないことに注意してください、しかし、あなただけの彼女の最大の長さを伝える必要があります。例えば、色のストライプ{2 2 4 1 5 6 3 1 5 6}を与えられました。エヴァの好きな色を{2 3 1 5 6}と彼女の好きな順序で与えられている場合、彼女は、4つの可能な最良の解{2 2 1 1 1 5 6}、{2 2 1 5 5 5 6}、{2 2 1を有しています5 5 6 6}、および{2 2 3 1 5 6}。
入力仕様:
各入力ファイルには、1つのテストケースが含まれています。各場合について、最初の行は、正の整数含ま N(関与する色の総数である(したがって、色は1から番号が付けられている≤) N)を。そして、次の行は正の整数で始まり M(続く≤) 彼女のお気に入りのために与えられたMエヴァの好きな色番号。最後に第三のラインは正の整数で始まり L(続く所与のストライプの長さ≤)、 ストライプ上のL色。行のすべての数字は、スペースで区切られています。
出力仕様:
各テストケースのために、単にラインでエヴァのお気に入りのストライプの最大長さを印刷します。
サンプル入力:
6
5 2 3 1 5 6
12 2 2 4 1 5 5 6 3 1 1 5 6
サンプル出力:
7
最大長さが減少LIS--配列:
アルゴリズム設計は
次数Nの配列の長さとして定義され、順番に番号に対応する要素としてエヴァ好きなカラーインデックス番号は、例えば、好きな色は、23156に与えられましたその後、注文[2] = 1、順番 [3] = 2 ...... 配列ビーズ所定のメモリアレイの定義は、DPは、[I]は、[i]は、ほとんどの端部の要件を満たすために配列を表す配列、DPを定義します長さが長いです。次いで、0 <= iは[i]が注文間で0 <= jの<満足を見出すために、N <>を注文= [j]が最大要素値MAX、DP [I] = MAX(MAX DP 、1) 。DPは最大値も望まれている見つけるために、アレイを横切ります。
1 使用して 名前空間はstdを、 2 INT メイン(){ 3 int型N、M、L、。 4 のscanf(" %d個の%のD "、&N、&M)。 5 INTの順[N + 1 ] = { 0 }。 6 用(int型 = Iを1 ; I <= M; ++ I){ // 给ため数组赋值 7 のscanf(" %dを"、&A )。 8 オーダー[A] = I。 9 } 10 のscanf(" %dの"&L) 。11 INT A [L] = MAXLEN 0、DP [L] = { 0 }; 12である ため(int型 I = 0 ;私はL <; ++ I) 13は scanfの(" %のD 」、 &[I]); 14 用(INT I = 0 ;私は<Lを、Iは++){ // 解決DPは、アレイ 15 IF(受注[I]]が> 0){ // 好きな色であり、 16 INT MAX = 0 ; 17 用(INT J = 0; J; <I J ++)// =順0〜I-1との間を満たすため[i]を見つける> [J] DPの最大値の 18である IF(注文[A [I]]> = オーダー[ [J]) 19。 MAX = MAX(DP [J]、MAX); 20 [I] = MAX(MAX + DP 1、1); // 更新DP配列値 21は MAXLEN = MAX(MAXLEN、DP [I] ); // の最大長更新 22である } 23である } 24 のprintf(" %のD " 、MAXLEN); 25 リターン 0 ; 26れます }
LCS--最長共通部分列
するように設計されたアルゴリズム
A、B間の最長共通サブシーケンスを見つけるために、色のようなアレイに格納されたシーケンス番号、ビーズのストリング所与のメモリアレイBのシーケンスの定義を定義 色を繰り返すことができるので、すなわち、サブシーケンスは、要素を繰り返すことができ、状態遷移方程式は、次のとおり
もし[i]を== B [j]は、
もし[I]!= B [j]は、
ボーダーケース:
DP [i]は[0] DP [0] [j] = 0 =(0 <= I <= M、0 <= jの<= L)
1 使用して 名前空間はstdを、 2 INTの DP [ 205 ] [ 10005 ]。 3 INT メイン(){ 4 整数N、M、L。 5 のscanf(" %d個の%のD "、&N、&M)。 6 INT A [M + 1 ] = { 0 }。 図7は、 のために(int型 I = 1 ; I <= M; ++ I) 8 のscanf(" %dの"、&A [I])。 9 のscanf(" %dの"、&L)。 10 INT B [L + 1 ] = { 0 }。 11 のためには、(int型 i = 1 ; iが= Lを<; ++ i)は、 12 のscanf(" %dの"、&B [I])。 13 のためには、(int型 iは= 1 ; I <= M ++ I) 14 のための(INT J = 1 ; J <= L; ++ j)が 15 であれば([I] == B [J]) 16 のDPを[I] [J] = MAX(DP [I]、[J- 1 ]、DP [I- 1 ] [J- 1])+ 1 。 17 他 18 DP [I] [J] = MAX(DP [i]は[J- 1 ]、DP [I- 1 ] [J])。 19 のprintf(" %dの" 、DP [M] [L])。 20 リターン 0 ; 21 }