动态规划——LCS

动态规划在解决最长公共子序列(LCS)问题时,通常涉及四个步骤:验证最优子结构、递归解法、计算LCS长度以及处理重叠子问题。以序列X和Y为例,当它们的对应元素相等时,LCS包含该元素;反之,LCS不包含。递归公式为c[i,j]=0 (i=0或j=0),c[i,j]=c[i-1,j-1]+1 (xi=yj),c[i,j]=max{c[i-1,j],c[i,j-1]} (xi≠yj)。通过从底向上计算c[i,j],避免重复解决子问题。" 112688465,9952424,使用差分数组解决分苹果问题,"['数据结构', '算法', 'C++']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

动态规划分为四个步骤:
1.判断问题是否具有最优子结构
这里以LCS为例,X={x1,x2,…,xi};Y={y1,y2,…,yj}。最长公共子序列Z={z1,z2,…,zk};
①如果xi=yj,那么zk=xi=yj,且Zk-1是序列Xi-1和Yj-1的LCS;
②如果xi≠yj,那么zk≠xi;且Zk是序列Xi-1和Yj的LCS;
③如果xi≠yj,那么zk≠yj;且Zk是序列Xi和Yj-1的LCS;

2.一个递归解
设c[i,j]是Xi和Yj的LCS的长度,i=0或j=0时,c[i,j]=0;
c[i,j]=0 (i=0或j=0)
c[i,j]=c[i-1,j-1] + 1 (i,j>0;xi=yj)
c[i,j]=max{c[i-1,j],c[i,j-1]} (i,j>0;xi≠yj)

3.计算LCS的长度
c[i,j]为递归解,那么有多少个不同的递归解呢?O(m*n)。即要有重叠子问题,而不是每次都要解决新的问题。至于重叠子问题,需从底向上求。每次只需索引之前较小规模的子问题即可。
从底向上,求解c[i,j]。

#include <list>
#include <vector>
#include <iostream>
using namespace std;

int lcg_length(const string &X, const string &Y)
{
    if(X.empty() || Y.empty())
        return 0;
    int m = X.size();
    int n = Y.size();
    vector<vector<int>> c;
    for(int i = 0; i < m+1; ++ i)
    {
        vector<int> tmp(n+1, 0);
        c.push_back(tmp);
    }
    for(int i = 1; i <= m; ++ i) 
    {
        for(int j = 1; j <= n; ++ j)
        {
            if(X.at(i-1) == Y.at(j-1))
                c[i][j] = c[i-1][j-1] + 1;
            else {
                c[i][j] = max(c[i-1][j], c[i][j-1]);
            }
        }
    }
    return c[m][n];
}
int main()
{
    int len = lcg_length("ABCBDAB", "BDCABA");
    system("pause");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值