最長共通部分系列
おもにこのサイトを参考とした。
すごくわかりやすい。途中にある神スライドも参考に。
http://d.hatena.ne.jp/naoya/20090328/1238251033
上のサイトを自分なりにまとめた結果
LCS(i,j)の決め方はこのようになる
1一番後ろの要素が同じとき
if(a[i]==b[j])LCS(i,j)= LCS(i-1,j-1)+1;
2一番後ろの要素が異なるとき
if(a[i] != b[j]){
LCS(i,j)=max(LCS(i-1,j),LCS(i),j-1);
}
って感じにまとめられる。だいぶ端折ったけどw
以下は講義で使われた問題
http://judge.u-aizu.ac.jp/onlinejudge/lesson.jsp?id=ALDS1
最長共通部分系列
最長共通部分系列問題(longest-common-subsequence problem)は、2つの与えられた系列X =
ある系列ZがXとY両方の部分系列であるとき、ZをXとYの共通部分系列という。例えば、X = , Y = とすると、系列はXとYの共通部分列である。しかし、系列はXとYの最長共通部分系列ではない。なぜなら、その長さは3であり、長さ4の共通部分系列が存在するからである。長さが5以上の共通部分系列が存在しないから、系列はXとYの最長共通部分系列の1つである。
問題
与えれた2つの文字列(系列)X、Yに対して、最長共通部分系列Zの長さを出力するプログラムを作成せよ。与えられる文字列はアルファベットのみで構成される。
制約
1 ≤ X, Yの長さ ≤ 1,000
入力
複数のデータセットが与えられる。最初の行にデータセットの数nが与えられる。続く2×n行にデータセットが与えられる。各データセットでは2つの文字列X, Yがそれぞれ1行に与えられる。
出力
各データセットについてX, Yの最長共通部分系列Zの長さを1行に出力せよ。
以下回答
int LCS[MAX][MAX]; void ini(){ for(int i=0;i<MAX;i++) for(int j=0;j<MAX;j++) LCS[i][j] = 0; } int solve(string a,string b){ if(b.length() > a.length()) swap(a,b); int I = a.length(),J=b.length(); for(int i=1;i<=I;i++){ for(int j=1;j<=J;j++){ cout << fuck << endl; if( a[i-1]== b[j-1])LCS[i][j]=LCS[i-1][j-1]+1; else LCS[i][j] = max(LCS[i][j-1],LCS[i-1][j]); } } return LCS[I][J]; } int main(fuck){ string a,b; int n; cin >> n; for(int i=0;i<n;i++){ ini(); cin >> a; cin >> b; cout << solve(a,b) << endl; /* for(int i=0;i<=a.length();i++){ for(int j=0;j<=b.length();j++){ cout << LCS[i][j] << " " ; } cout << endl; } */ } }