Namareba食べたい

備忘録てきなもの。だらだら書いていきます。

最長共通部分系列

おもにこのサイトを参考とした。
すごくわかりやすい。途中にある神スライドも参考に。
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 = とY = の最長共通部分系列を求める問題である。

ある系列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;
    }
    */
    
  }

}