• 最长上升子序列


    https://www.cnblogs.com/frankchenfu/p/7107019.html 借鉴

    最长上升子序列就是在一个序列中找到非递减的子序列,子序列可以不是连续的

    一种方法就是固定一个i在0到i中找j j取或不取将影响到i 更新i的值 复杂度是O(n^2)

    #include<cstdio>
    const int MAX=1001;
    int a[MAX];
    int lis(int x)
    {
        int num[MAX];
        for(int i=0;i<x;i++)
        {
            num[i]=1;
            for(int j=0;j<i;j++)
            {
                if(a[j]<a[i]&&num[j]+1>num[i])
                       num[i]=num[j]+1;
            }
        }
        int maxx=0;
        for(int i=0;i<x;i++)
            if(maxx<num[i])
                maxx=num[i];
        return maxx;
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        return !printf("%d
    ",lis(n));
    }

    今天考到的第二个方法是用栈优化的 复杂度是O(nlgn)

    用二分的思想....【其实我也不是特别理解】 这个二分其实是用stl lower_bound实现的

    dp[i]=长度为i+1的上升子序列中末尾元素的最小值(不存在的话就是INF)

    http://blog.csdn.net/zhangyx_xyz/article/details/50949957【参考】


    几乎都没有用过的我感到非常惭愧 还去百度了一下是什么

    函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置


    #include<cstdio>
    #include<algorithm>
    const int MAXN=200001;
    
    int a[MAXN];
    int d[MAXN];
    
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        d[1]=a[1];
        int len=1;
        for(int i=2;i<=n;i++)
        {
            if(a[i]>d[len])
                d[++len]=a[i];
            else
            {
                int j=std::lower_bound(d+1,d+len+1,a[i])-d;
                d[j]=a[i]; 
            }
        }
        printf("%d
    ",len);    
        return 0;
    }


  • 相关阅读:
    2014 10 07 ················男人感悟100(转自MOP)
    BFS和DFS优先搜索算法
    求素数算法-网摘
    DP问题各种模型的状态转移方程 (转)
    srand函数
    #include<algorithm>
    常用算法一(分治算法)
    杭电ACM题目分类
    四方定理
    五大常用算法之二:动态规划算法
  • 原文地址:https://www.cnblogs.com/wyboooo/p/9643440.html
Copyright © 2020-2023  润新知