C - 共通部分
与えられたシーケンスのサブシーケンスを省略いくつかの要素(可能なし)と指定された配列です。与えられたシーケンスX = <X1、X2、...、XM>他の系列Z =厳密に増加シーケンスが存在する場合、<Z1、Z2、...、ZK> Xのサブシーケンスは<I1、I2、...そのようなすべてのjについて= 1,2、...、K、xijを= ZJそのXのインデックスの、IK>。例えば、Z = <、B、Fは、C>インデックスシーケンス<1、2、4、6>とX =のサブ<A、B、C、F、B、C>です。二つの配列XとY与えられた問題は、XとYの最大長の共通部分列の長さを見つけることです
プログラムの入力は、テキストファイルからです。ファイルに設定された各データは、与えられたシーケンスを表す2つの文字列が含まれています。配列は、空白の任意の数によって分離されています。入力データが正しいです。データ標準出力別の行の先頭から最大長共通サブシーケンスの長さにプログラム印刷物の各セットのために。
入力
abfcab abcfbc プログラミングコンテスト MNP ABCD
出力
4 2 0
サンプル入力
abfcab abcfbc プログラミングコンテスト MNP ABCD
サンプル出力
4 2 0
最長のシーケンスの増加:質問をすることを意図している
のアイデアを:リニアDP基本的な
状態:DP [i] [j]は、最も長い文字列は、配列上昇する前に、私は文字列要素S1、S2のj番目の要素の前に終了を表す
目標を:MAX (DP [I] [J])
の状態遷移:IF(S1 [i]が== S2 [K]) DP [I] [K] = MAX(DP [I] [K]、DP [1-I] [ K-1])+ 1、。。
他DP [I] [K] = MAX(DP [I-1] [K]、DP [I] [K-1]);。。
決定:S1 [i]をS2と[J平等]
コードは次のとおりです。
書式#include <iostreamの> の#include <cstdioを> する#include <CStringの> の#include <アルゴリズム> 書式#include < 文字列 > の#defineは長い長いint型北韓 使用して 名前空間はstdを、 int型の DP [ 1005 ] [ 1005 ]; チャー S1〜[ 1005 ]、S2 [ 1005 ]。 INT メイン() { 一方(scanf関数(" %sの%sの"、S1 + 1、S2 + 1)!= EOF) { memsetの(DP、0、sizeof(DP))。// 初始化 INT SS1 = STRLEN(S1 + 1)、SS2 = STRLEN(S2 + 1 )。 INT MAX = - 1を。 以下のために(int型 I = 1 ; I <= SS1; I ++ ) のための(INT K = 1 ; K <= SS2あり、k ++ ) { 場合(S1 [i]が== S2 [K]) DP [I] [K] = MAX(DP [I] [K]、DP [I- 1 ] [K- 1 ])+ 1 。 他の DP [i]の[K] = MAX(DP [I-1 ] [k]は、DP [I] [K- 1 ])。 MAX = MAX(MAX、DP [I] [K])。 } COUT << MAX << ENDL。 } 戻り 0 。 }