poj1458 Common Subsequence 最长公共序列 解题报告(附详细分析)

这道题是动态规划的典型题目。

动态方程:

if(str1[i] == str2[j])
MaxLen[i][j] = MaxLen[i-1][j-1] + 1;//比较到两个字母相同时,把前一状态的值加1就得到当前的最长公共序列
else
MaxLen[i][j] = max(MaxLen[i][j-1], MaxLen[i-1][j]);//比较到两个字母不同时,分别将两个字符串后移一个字符,比较两种情况哪个得到的公共子序列最长


思路:把str1和str2分别比较它们的前i,j的字符串的公共序列,把求最大分解为求每个子序列的最大公共序列,然后用数组存储它们的解,自下而上,求出Maxlen[1][1],就能求出Maxlen[2][2],一直到Maxlen[i][j],从而提高效率。应该说是一种优化的穷举法。

动态规划算法是这样的:

先求出Maxlen[1][1]一直到Maxlen[1][j],然后就可以求出Maxlen[2][1]一直到Maxlen[2][j],一直到最后就能得到Maxlen[i][j].得到一个矩阵,Maxlen[len1][len2]就是问题的解。


#include <iostream>
#define MAX_LEN 201
using namespace std;
char str1[MAX_LEN];
char str2[MAX_LEN];
int MaxLen[MAX_LEN][MAX_LEN];
int main()
{
	while (scanf("%s%s", str1+1, str2+1) != EOF)	//scacnf读取字符串时不要加&,因为数组名本身就是地址.并且没有输入时scanf会返回EOF
	{
		int Len1 = strlen(str1 + 1);
		int Len2 = strlen(str2 + 1);
		int i, j;
		for(i = 0; i <= Len1; i++)
			MaxLen[i][0] = 0;		//注意初始化边界条件,Maxlen[i][0]表示str1[i]与str2[0]的公共序列,显然是0
		for(j = 0; j <= Len2; j++)
			MaxLen[0][j] = 0;
		for(i = 1; i <= Len1; i++)
		{
			for(j = 1; j <= Len2; j++)
				if(str1[i] == str2[j])
					MaxLen[i][j] = MaxLen[i-1][j-1] + 1;	//比较到两个字母相同时,把前一状态的值加1就得到当前的最长公共序列
				else
					MaxLen[i][j] = max(MaxLen[i][j-1], MaxLen[i-1][j]);	//比较到两个字母不同时,分别将两个字符串后移一个字符,比较两种情况哪个得到的公共子序列最长
		}
		printf("%d\n", MaxLen[Len1][Len2]);
	
	
	}
		return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值