动态规划——最长公共子序列LCS

有了最长公共子序列的基础,我们就很快能理解什么是最长公共子序列了,看一道例题hud1159:
A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = <x1, x2, …, xm> another sequence Z = <z1, z2, …, zk> is a subsequence of X if there exists a strictly increasing sequence <i1, i2, …, ik> of indices of X such that for all j = 1,2,…,k, xij = zj. For example, Z = <a, b, f, c> is a subsequence of X = <a, b, c, f, b, c> with index sequence <1, 2, 4, 6>. Given two sequences X and Y the problem is to find the length of the maximum-length common subsequence of X and Y.
The program input is from a text file. Each data set in the file contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct. For each set of data the program prints on the standard output the length of the maximum-length common subsequence from the beginning of a separate line.
不翻译了,太简单 ,不会翻译。
Input
abcfbc abfcab
programming contest
abcd mnp
Output
4
2
0
Sample Input
abcfbc abfcab
programming contest
abcd mnp
Sample Output
4
2
0
我们用str1,和str2来记录两个数列的长度,动态规划就变成了f(str1,str2)的问题了。f(str1,str2)表示最长公共子序列的长度。
比如
f(1,1) 就是 a a公共子序列的长度 为1
f(3,2) 就是 abc ab公共子序列的长度 为2
f(5,3) 就是 abcfb abf的公共子序列长度 为3
看完这几个例子,这个函数我们理解了。
如何求呢?我们发现
如果a[1] == b[1] (注:数组从0开始,且a、b表示两个字符数组)
那么显然f(2,2) = f(1,1) + 1
如果a[2] != b[1]
那么f(2,1) = max(f(1,1), f(2,0))
这里要说明一下,这里就是减去最后一个来递推,这里是保证递推的完整性,保证每一个f(str1,str2)都是有意义的,保证最终结果有效。
所以递推的代码就出来了:

for(int i = 1; i <= str1; i++)
for(int j = 1; j <= str2; j++)
	if(a[i - 1] == b[j - 1])
	f[i][j] = f[i - 1][j - 1] + 1;
	else
	f[i][j] = max(f[i - 1][i], f[i][j - 1]);

f函数不从0开始是不越界,因为有i - 1,防止出现负数。
完整代码:

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int f[1001][1001];
int main()
{
	char a[1001], b[1001];
	while(scanf("%s%s", a, b) != EOF)
	{
		memset(f, 0, sizeof(f));
		int num;
		int str1 = strlen(a);
		int str2 = strlen(b);
		for(int i = 1; i <= str1; i++)
		for(int j = 1; j <= str2; j++)
		if(a[i - 1] == b[j - 1])
		f[i][j] = f[i - 1][j - 1] + 1;
		else
		f[i][j] = max(f[i - 1][i], f[i][j - 1]);
		cout << f[str1][str2] << endl;
	}
	return 0;
 } 

猜你喜欢

转载自blog.csdn.net/yezi_coder/article/details/103943513
今日推荐