问题描述
给定三个长度不超过200的整数序列X,Y,Z,求他们的最长公共子序列。序列中的数字均为10000以内的正整数。
例如:下列三个序列的最长公共子序列长度为4,为<1,3,9,15>。
X=<1,3,5,7,9,11,13,15>
Y=<0,1,3,6,9,12,15,18>
Z=<1,2,3,4,9,10,15,20>
输入格式
第一行,三个整数a,b,c分别代表x,y,z三个序列的长度
第二行,a个空格间隔的整数,表示x序列
第二行,b个空格间隔的整数,表示y序列
第二行,c个空格间隔的整数,表示z序列
输出格式
一个整数,表示所求答案
样例输入
8 8 8
1 3 5 7 9 11 13 15
0 1 3 6 9 12 15 18
1 2 3 4 9 10 15 20
样例输出
4
/*
状态:
f[i][j][k]表示x数组的前i个与y数组的前j个与z数组的前k个中最长公共子序列的长度
方程:1.当x[i] == y[j] == z[k]:
f[i][j][k] = f[i - 1][j - 1][k - 1] + 1
(f[i - 1][j - 1]表示x数组的前i - 1个与y - 1数组的前j个中,z数组的前k - 1个最长公共子序列的长度
再加当前相同的x[i]与y[j]与z[k]这一个)
其他:
f[i][j][k] = max(f[i][j - 1][k], f[i][j][z - 1], f[i - 1][j][z])
(f[i][j - 1][z]表示x数组的前i个与y数组的前j - 1个与z数组的前k个中最长公共子序列的长度)
(f[i - 1][j][z], f[i][j][z - 1]以此类推)
(再选最大值)
边界:
(1) 1 <= i <= m
(2) 1 <= j <= n
(3) 1 <= k <= s
问题:
1.注意数组大小
*/
#include
using namespace std;
int x[200 + 5] = { };
int y[200 + 5] = { };
int z[200 + 5] = { };
int f[200 + 5][200 + 5][200 + 5] = { };
int main()
{
int m, n, s;
scanf("%d %d %d", &m, &n, &s);
for(int i = 1; i <= m; i++){
scanf("%d", &x[i]);
}
for(int i = 1; i <= n; i++){
scanf("%d", &y[i]);
}
for(int i = 1; i <= s; i++){
scanf("%d", &z[i]);
}
for(int i = 1; i <= m; i++){
for(int j = 1; j <= n; j++){
for(int k = 1; k <= s; k++){
if(x[i] == y[j] && y[j] == z[k]){
f[i][j][k] = f[i - 1][j - 1][k - 1] + 1;
}
else{
f[i][j][k] = max(f[i - 1][j][k], max(f[i][j - 1][k], f[i][j][k - 1]));
}
}
}
}
printf("%d", f[m][n][s]);
return 0;
}