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

问题描述:

公共子序列:

动态规划求解步骤

Step 1: 分析最优解的性质,刻画其结构特征

Step 2: 递归地定义最优解

第一种情况:序列X的第i个元素与序列Y的第j个元素相等,则序列X、Y公共子序列长度=X、Y除去i,j位置元素后的

                     公共子序列长度+1

第二种情况:序列X的第i个元素与序列Y的第j个元素不相等,则公共子序列长度=序列X除去i位置元素与序列Y的最

                      长公共子序列  长度或序列Y除去j位置元素与序列X的最长公共子序列长度

Step 3: 自底向上计算子问题的最优解

二维数组d[i,j]用来记录X[i]和Y[j]最长子序列长度二维数组p[i,j]用来记录X[i]和Y[j]最长子序列的位置

Step 4: 构造问题的最优解 

伪代码解析

1.求解最长子序列

Longest-Common-Subsequence(X, Y)
输入:两个序列X,Y
输出:最长公共子序列
Input: Two strings 𝑿, 𝒀.
Output: Longest common subsequence of 𝑋 and 𝑌.
𝑚 ← length(𝑋);  #序列X的长度为m
𝑛 ← length(𝑌);   #序列Y的长度为n
步骤1:构建两个数组d[m,n],p[m,n](m行n列的二维数组)分别用来记录最长公共子序列的长度,
      公共子序列元素的位置
Let 𝑑[0. . 𝑚, 0. . 𝑛] and 𝑝[0. . 𝑚, 0. . 𝑛] be two new 2-dimension arrays;
步骤2:将二维数组d[m,n]的第一行,第一列置为0,即任何序列与空序列的最长公共子序列的长度均为0
for 𝑖 ← 0 𝑡𝑜 𝑚 do
    𝑑 [𝑖, 0] ← 0;
end
for 𝑗 ← 0 𝑡𝑜 𝑛 do
    𝑑 [0, 𝑗] ← 0;
end
步骤3:通过两层循环实现二维数组d[m,n]的所有元素的按行遍历,每一个单元格根据条件进行判断
for 𝑖 ← 1 𝑡𝑜 𝑚 do
    for 𝑗 ← 1 𝑡𝑜 𝑛 do
        if X[i] 𝑖𝑠 𝑒𝑞𝑢𝑎𝑙 𝑡𝑜 Y[J] then
            𝑑 [𝑖, 𝑗] ← 𝑑 [𝑖 − 1, 𝑗 − 1] + 1;
            𝑝[𝑖, 𝑗] ←”LU”;    //”LU” 表示矩阵左上角.
        end
        else if 𝑑[𝑖 − 1, 𝑗] ≥ 𝑑[𝑖, 𝑗 − 1] then
            𝑑 [𝑖, 𝑗 ]← 𝑑 [𝑖 − 1, 𝑗 ];
            𝑝[𝑖, 𝑗] ←”U”;    //”U” 表示矩阵上边.
        end
        else
            𝑑 [𝑖, 𝑗]← 𝑑 [𝑖, 𝑗 − 1] ;
            𝑝[𝑖, 𝑗] ←”L”;   //”L” 表示矩阵左边.
        end
       end
end
步骤4:返回二维数组d,p
return 𝑑, 𝑝;

 2.输出最长子序列

#创建递归程序,实现程序遍历
Print-LCS(𝑝, X, 𝑖, 𝑗)
#输入  𝒑:二维最长公共子序列数组 X:求解的序列 i,j分别为求解序列X[i],Y[j]的索引
Input: Array 𝒑 generated from Longest-Common-Subsequence, string 𝑿, index 𝒊 and 𝒋.
Output: Output the longest common subsequence of 𝑋[1. . 𝑖] and 𝑌[1. . 𝑗].
步骤1:如果索引i,j等于0,结束递归调用
if 𝑖 𝑖𝑠 𝑒𝑞𝑢𝑎𝑙 𝑡𝑜 0 𝑜𝑟 𝑗 𝑖𝑠 𝑒𝑞𝑢𝑎𝑙 𝑡𝑜 0 then
    return NULL;
end
步骤2:如果𝑝 [𝑖, 𝑗]=“𝐿𝑈”,则表示X[i]=Y[j],即上文中的第一种情况
if 𝑝 [𝑖, 𝑗] 𝑖𝑠 𝑒𝑞𝑢𝑎𝑙 𝑡𝑜 “𝐿𝑈” then
    Print-LCS(𝑝, 𝑋, 𝑖 − 1, 𝑗 − 1);
    print X[i];
end
如果𝑝 [𝑖, 𝑗]=“𝑈”,则最长子序列X[i,j]=X[i-1,j],即上文中的第二种情况中第一种
else if 𝑝 [𝑖, 𝑗] 𝑖𝑠 𝑒𝑞𝑢𝑎𝑙 𝑡𝑜 “𝑈” then
    Print-LCS(𝑝, 𝑋, 𝑖 − 1, 𝑗);
end
如果𝑝 [𝑖, 𝑗]=“𝑈”,则最长子序列X[i,j]=X[i,j-1],即上文中的第二种情况中第二种
else
    Print-LCS(𝑝, 𝑋, 𝑖, 𝑗 − 1);
end

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值