#include <stdio.h>
#include <windows.h>
# define MAX(a, b) ((a) > (b) ? (a) : (b))
int LCS1(int * a, int * b, int n, int m);
int LCS2(int * a, int * b, int n, int m);
int LCS3(int * a, int * b, int n, int m);
int LCS4(int * a, int * b, int n, int m);
int main(void){
int a[] = {8,4,6,5,-1,2,3,9};
int b[] = {1,2,7,2,-1,3,9};
int n = sizeof(a)/sizeof(int);
int m = sizeof(b)/sizeof(int);
printf("%d\n", LCS1(a, b, n, m));
printf("%d\n", LCS2(a, b, n, m));
printf("%d\n", LCS3(a, b, n, m));
printf("%d\n", LCS4(a, b, n, m));
system("pause");
return 0;
}
//递归
int LCS1(int * a, int * b, int n, int m){
if(0 == n || 0 == m || NULL == a || NULL == b)
return 0;
if(a[n-1] == b[m-1])
return LCS1(a, b, n-1, m-1) + 1;
return MAX(LCS1(a, b, n-1, m), LCS1(a, b, n, m-1));
}
//动态规划1
int LCS2(int * a, int * b, int n, int m){
if(0 == n || 0 == m || NULL == a || NULL == b)
return 0;
int ** dp = (int**)calloc((n+1), sizeof(int*));
for(int i = 0; i <= n; i++){
dp[i] = (int*)calloc((m+1), sizeof(int));
}
//dp[j][k]为a前j个元素和b前k个元素的最长公共子序列
for(int j = 1; j <= n; j++){
for(int k = 1; k <= m; k++){
if(a[j-1] == b[k-1]){
dp[j][k] = dp[j-1][k-1] + 1;
}
else{
dp[j][k] = MAX(dp[j][k-1], dp[j-1][k]);
}
}
}
return dp[n][m];
}
//动态规划2 优化空间用滚动数组
int LCS3(int * a, int * b, int n, int m){
if(0 == n || 0 == m || NULL == a || NULL == b)
return 0;
int ** dp = (int**)calloc((3), sizeof(int*));
for(int i = 0; i <= 2; i++){
dp[i] = (int*)calloc((m+1), sizeof(int));
}
//dp[j][k]为a前j个元素和b前k个元素的最长公共子序列
for(int j = 1; j <= n; j++){
for(int k = 1; k <= m; k++){
if(a[j-1] == b[k-1]){
dp[j&1][k] = dp[(j-1)&1][k-1] + 1;
}
else{
dp[j&1][k] = MAX(dp[j&1][k-1], dp[(j-1)&1][k]);
}
}
}
return dp[n&1][m];
}
//动态规划3 优化用一维数组
int LCS4(int * a, int * b, int n, int m){
if(0 == n || 0 == m || NULL == a || NULL == b)
return 0;
int * dp= (int*)calloc((m+1), sizeof(int));
//dp[k]为某行前某个元素和b前k个元素的最长公共子序列
for(int j = 1; j <= n; j++){
int temp = 0;
for(int k = 1; k <= m; k++){
int topleft = temp;
temp = dp[k];
if(a[j-1] == b[k-1]){
dp[k] = topleft + 1;
}
else{
dp[k] = MAX(dp[k-1], dp[k]);
}
}
}
return dp[m];
}