三个序列的最长公共子序列

问题描述

给定三个长度不超过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;
} 

 

你可能感兴趣的:(信奥,习题)