C++编程题-最长公共子序列思路

问题描述:

最长公共子序列(LongestCommonSubsequence,LCS)的问题描述为:给定两个字符串(或数字序列)A和B,求一个字符串,使得这个字符串是A和B的最长公共部分(子序列可以不连续)。如样例所示,字符串“sadstory”与“adminsory”的最长公共子序列为“adsory”,长度为 6。

思路:

暴力的解法:设字符串A和B的长度分别是n和m,那么对两个字符串中的每个字符,分别有选与不选两个决策,而得到两个子序列后,比较两个子序列是否相同又需要 O(max(m,n)),这样总复杂度就会达到O(2"+xmax(m,n)),无法承受数据大的情况。直接来看动态规划的做法(下文的LCS均指最长公共子序列)。令 dp[i][j]表示字符串A的i号位和字符串B的j号位之前的LCS长度(下标从1开始),如 dp[4][5]表示“sads”与“admin”的 LCS 长度。那么可以根据 A[i]和 B[]的情况,分为两种决策:
① 若 A[] = B[j],则字符串 A 与字符串 B的 LCS 增加了1位,即有 dp[i][j]=dp[i-1][j-1]+1。例如,样例中 dp[4][6]表示“sads”与“admins”的 LCS 长度,比较 A[4]与 B[6],发现两者都是's',因此 dp[4][6]就等于 dp[3][5]加1,即为 3。
② 若 A[]!= B[],则字符串A的i号位和字符串B的j号位之前的 LCS 无法延长,因此 dp[i][]将会继承 dp[i-1][]与 dp[i][j-1]中的较大值,即有 dp[i][]=max{dp[i-1][j],dp[i][j-1]}。例如,样例中 dp[3][3]表示“sad”与“adm”的 LCS 长度,我们比较 A[3]与 B[3],发现'd'不等于'㎡',这样 dp[3][3]无法再原先的基础上延长,因此继承自“sa”与“adm”的LCSsad”与“ad”的 LCS 中的较大值,即“sad”与“ad”的 LCS 长度--2.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值