POJ-1458 最长公共子序列

这个题的意思就是说:

给一个序列 A 和 B ,让你求他们的共同的子序列的长度,这些子序列可以不在原来的字符串中连续排列。

这个题的话,我们可以使用动态规划的思路,我们假设 MaxLen [ i ] [ j ] 是 A 串和 B 串中从一开始的,A 串中的的第 i 个字符和B 串中的第 j 个字符的最长公共子序列的长度。

我们可以知道 MaxLen[i][0]是0,并且 MaxLen[0][j]也是0,这是边界条件。

然后对于以后的如果 a串的第 i个字符和 b串的第 j个字符相等的话,我们就可以让 MaxLen [i][j]加一,如果不相等的话我们就从

maxlen[i][j-1] 和maxlen[j][i-1]中选一个大的出来作为它的值。

对于一个不做证明,第二个也很好证明,主要是因为,既然 MaxLen [i][j] 不大于MaxLen [i][j-1]和 MaxLen [i-1][j],并且 MaxLen [i][j]

不小于 MaxLen [i][j-1] 和 MaxLen [i-1][j] ,所以,他们可以说是相等的关系。

怎么证明这个,对于不小于不再作证明了,不大于的话我们用反证就可以了。

因为如果它大于 减一 这个类的话,说明,第 i 个字符起作用了,因为 i-1 并没有这个字符,说明它就是最后一个字符,同理 j-1也是最后一个字符,既然他们都是最后一个字符,并且都起了作用, 说明他们相等,而我们的前提是 i-1 不等于 j-1,所以推出矛盾,假设不成立。

#include <iostream>
#include <cstring>
using namespace std;
char sz1[1000];
char sz2[1000];
int MaxLen[1000][1000]; 
using namespace std;
int main()
{
	while (cin>>sz1>>sz2) {
		int len1=strlen(sz1);
		int len2=strlen(sz2);
		for (int i=0;i<=len1;i++) {
			MaxLen[i][0]=0;
		}
		for (int j=0;j<=len2;j++) {
			MaxLen[0][j]=0;
		}
		for (int i=1;i<=len1;i++) {
			for (int j=1;j<=len2;j++) {
				if (sz1[i-1]==sz2[j-1]) {
					MaxLen[i][j]=MaxLen[i-1][j-1]+1;
				}
				else {
					MaxLen[i][j]=max(MaxLen[i-1][j],MaxLen[i][j-1]);
				}
			}
		}
		cout<<MaxLen[len1][len2]<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41090676/article/details/84386942
今日推荐