zoukankan      html  css  js  c++  java
  • nlogn求LIS(树状数组)

    之前一直是用二分

    但是因为比较难理解,写的时候也容易忘记怎么写。

    今天比赛讲评的时候讲了一种用树状数组求LIS的方法

    (1)好理解,自然也好写(但代码量比二分的大)

    (2)扩展性强。这个解法顺带求出以i为结尾的LIS,而很多题要用到这个数组来做

    而二分的做法求得是当前长度下的最小值,不容易拓展。

    #include<bits/stdc++.h>
    #define REP(i, a, b) for(register int i = (a); i < (b); i++)
    #define _for(i, a, b) for(register int i = (a); i <= (b); i++)
    using namespace std;
    
    const int MAXN = 1e3 + 10;
    int a[MAXN], b[MAXN], n, m, ans; 
    int dp[MAXN], f[MAXN];
    
    inline int lowbit(int x) { return x & (-x); } 
    
    void motify(int x, int p)
    {
        for(; x <= m; x += lowbit(x))
            f[x] = max(f[x], p);
    }
    
    int get_max(int x)
    {
        int res = 0;
        for(; x; x -= lowbit(x))
            res = max(res, f[x]);
        return res;
    }
    
    int main()
    {
        scanf("%d", &n);
        _for(i, 1, n) scanf("%d", &a[i]), b[i] = a[i];
    
        sort(b + 1, b + n + 1);
        m = unique(b + 1, b + n + 1) - b - 1;
        _for(i, 1, n) a[i] = lower_bound(b + 1, b + m + 1, a[i]) - b;
        
        int ans = 0;
        _for(i, 1, n)
        {
            dp[i] = get_max(a[i] - 1) + 1;
            ans = max(ans, dp[i]);
            motify(a[i], dp[i]); 
        }
        printf("%d
    ", ans);
        return 0;
    }

    具体怎么做呢

    n方的算法有一步去枚举之前所有的元素比较耗时间

    可以用树状数组优化这一步,树状数组维护区间最大值

    把元素的值当作下标,dp值作为值

    a[i]表示当前值,dp[i]表示以i为结尾最长不下降子序列的长度

    则 dp[i] = get_max(a[i]) + 1

    也就是说,在小于等于当前值a[i]中,最大的dp值+1就是当前的答案

    不过这里有个细节,怎么区分最长不下降还是最长上升?

    如果你对原理理解透彻的话,这个问题其实很容易解决,你可以停下来自己推一下,检验一下自己理解了没有

    如果是最长不下降的话,dp[i] = get_max(a[i]) + 1

    如果最长上升的话, dp[i] = get_max(a[i]-1) + 1

    最后注意要离散化一下

    以下是最长上升子序列的模板

  • 相关阅读:
    微服务-分解应用程序从而实现更好的部署特性及可伸缩性
    <HTML5和CSS3响应式WEB设计指南>译者序
    使用亚马逊的Route53服务
    Java中测试异常的多种方式
    跑在路上的程序员随想
    使用ruby过程中遇到安装gem失败的一些通用解决方案
    Spring-Context之九:在bean定义中使用继承
    Spring-Context之八:一些依赖注入的小技巧
    配置ngnix
    PHP程序员进阶学习书籍参考指南
  • 原文地址:https://www.cnblogs.com/sugewud/p/9823222.html
Copyright © 2011-2022 走看看