【模型】LIS

1 篇文章 0 订阅
本文介绍了最长上升子序列(LIS)问题,包括两种解决方案:O(n^2)的时间复杂度的朴素动态规划方法和O(n log n)的优化算法。文章通过代码示例详细阐述了这两种方法的实现过程,并指出虽然定义有所调整,但不影响最终结果。最终,通过求解f数组确定最长上升子序列的长度。
摘要由CSDN通过智能技术生成

LIS

最长上升子序列,会有各种变种,比如说最长不下降子序列,最长不上升子序列等等,代码差不多,这里以最长上升子序列为例。最长上升子序列,就是在一个序列A中找到一个一个序列中最长的单调递增的子序列(可以不连续)。
LIS有两种解决方法法, O(n2) O ( n 2 ) & O(nlog2n) O ( n l o g 2 n ) ,在这里都给出。

§ § LIS O(n2) O ( n 2 )

朴素的DP,方程可以直接写出:
fi=maxfj+1,1ji,a[j]<a[i] f i = m a x f j + 1 , 其 中 1 ≤ j ≤ i , a [ j ] < a [ i ]
Ans=maxelementf A n s = m a x e l e m e n t f

code: c o d e :

int LIS(std::vector< int > &a) {
    int ans = 1; 
    std::vector< int > f(a.size(), 1);
    for (unsigned int i = 2; i <= a.size() - 1; i++) 
        for (unsigned int j = i - 1; j >= 1; j--) 
            if (a[i] > a[j] && f[i] < f[j] + 1) {
                f[i] = f[j] + 1;
                if (f[i] > ans)
                    ans = f[i];
            }
    return ans;
}

§ § LIS O(nlog2n) O ( n l o g 2 n )

我们对 f f 数组重新定义,fi定义为长度为i的上升子序列的最后一个元素(本人在程序中使用了vector,f中所有元素都往前平移一位,所以定义发生改变,但不影响结果),初始化 f[1]=a[1] f [ 1 ] = a [ 1 ] ,然后每插入一个 a[i] a [ i ] ,判断它和 f f 中最后一个元素的大小,如果大于,就插入,如果不大于的话,就从f中找到第一个大于a[i]的,插在后面(可以用upper_bound),
Ans=f.size() A n s = f . s i z e ( )

code: c o d e :

int LIS(std::vector< int > &a) {
    std::vector< int > f;
    f.push_back(a[1]);
    for (unsigned int i = 2; i < a.size(); i++)
        if (a[i] < f.back()) 
            f[std::upper_bound(f.begin(), f.end(), a[i]) - f.begin()] = a[i]; 
        else f.push_back(a[i]); 
    return f.size();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值