//============================================================================
// Name : 100题之20最长公共子序列.cpp
// Author :
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
using namespace std;
int f[100][100];
int path[100][100];
void print(int i,int j,int*a)
{
if(i<=0||j<=0)
return;
if(path[i][j]==1)
{
print(i-1,j-1,a);
cout<<a[i]<<" ";
}
else if(path[i][j]==2)
{
print(i-1,j,a);
}
else if(path[i][j]==3)
{
print(i,j-1,a);
}
}
//最长公共子序列
void compute_f(int *a,int m,int *b,int n)
{
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
if(a[i]==b[j]&&f[i][j]<f[i-1][j-1]+1)
{
f[i][j]=f[i-1][j-1]+1;
path[i][j]=1;
}
if(f[i][j]<f[i-1][j])
{
f[i][j]=f[i-1][j];
path[i][j]=2;
}
if(f[i][j]<f[i][j-1])
{
f[i][j]=f[i][j-1];
path[i][j]=3;
}
cout<<"f["<<i<<"]["<<j<<"]="<<f[i][j]<<endl;
}
}
}
void print1(int i,int j,int*a)
{
if(i<=0||j<=0)
return;
if(path[i][j]==1)
{
print(i-1,j-1,a);
cout<<a[i]<<" ";
}
}
//两个字符串的最长公共子字符串
int compute_f_1(int *a,int m,int *b,int n,int &max1,int&max2)
{
max1=0;
max2=0;
int max=0;
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
if(a[i]==b[j]&&f[i][j]<f[i-1][j-1]+1)
{
f[i][j]=f[i-1][j-1]+1;
path[i][j]=1;
if(max<f[i][j])
{
max=f[i][j];
max1=i;
max2=j;
}
}
cout<<"f["<<i<<"]["<<j<<"]="<<f[i][j]<<endl;
}
}
return max;
}
int main() {
int a[10]={0,2,4,4,1,2,1};
int b[10]={10,1,2,3,2,4,1,2};
int m=6;
int n=7;
int max1,max2;
cout<<compute_f_1(a, m, b, n,max1,max2)<<endl;
cout<<f[max1][max2]<<endl;
print1(max1,max2,a);
return 0;
}