• LIS——最长不下降子序列


    输入一个n,以及n个数据,输出最长的不下降的子序列

    大意:

    有两种思路:

    1.O(n^2)想法

    用一个num来记录以该数字为末数字的长度

    用一个if限制两个条件,后面小于前面并且后面的长度大于前面的长度+1那么说明需要更新了,最后只要遍历所有的数字在num中看以那个数字为开始点的长度最长。这个比较好理解

    #include<cstdio>
    const int MAX = 150;
    int a[MAX],num[MAX];
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i = 1; i<= n ;i++)
            scanf("%d",&a[i]);
        for(int i = 1; i <= n ; i++){
            num[i] = 1;
            for(int j = 1; j < i ; j++){
                if(a[i] > a[j] &&num[i] < num[j] + 1)
                num[i] = num[j]+1;
            }
        }
         int max = 0;
         for(int i = 1; i <= n ; i++){
                if(max < num[i])
                max = num[i];
         }
         printf("%d",max);
         return 0;
    }
    View Code

    2.O(n*logn)想法

    这个比较难以理解

    用b[k]来记录以该下标为长度,且最后一个数为它的数值

    b[1] = a[1],然后循环,判断是否a[i] > b[k],如果是的话,b长度就变长,值就变成a[i],否则的话从长度为1开始找一直找到以长度为k的,因为b是单调递增的,所以在其中找大于b[j],小于b[j+1]这个值的下标,就相当于在一个单调的串中找一个与要找的n相同的值,用二分法,不过以下标为二分的话,l = mid + 1,r = mid -1 ,返回l的值,左闭右开。

    #include<cstdio>
    using namespace std;
    const int MAX = 1010;
    int a[MAX],b[MAX];
    int main()
    {
        int n,k,l,r,mid;
        scanf("%d",&n);
        for(int i = 1; i <= n ; i++)
            scanf("%d", &a[i]);
        b[1] = a[1];
        int i;
        for(i = 2, k = 1;i <= n ; i++){
            if(a[i] > b[k]) b[++k] = a[i];//b[k]存储长度为k的最后一个数字
            else {
                 l = 1, r = k;
                while(l<= r){//二分查找
                   mid = (l + r)/2;
                  if(b[mid] < a[i]) l = mid + 1 ;
                  else if(b[mid] > a[i]) r = mid - 1;
                  else break;
                }
                b[l] = a[i];
            }
        }
        printf("%d
    ",k);
        return 0;
    }
    View Code

     也可以调用库函数 lower_bound  二分函数

    lower_bound(a, a + n, k) 用二分找a[i]大于k的最小的指针

    int dp[maxn];
    void solve()
    {
        fill(dp, dp + n ,inf);
        for(int i = 0 ; i < n ; i++)
            *low_bound(dp, dp + n ,a[i]) = a[i];
        printf("%d
    ",lower_bound(dp,dp+n,inf)-dp);
    }
    

      

  • 相关阅读:
    Python实现常用的数据结构
    Python实现一些常用排序算法
    python实现简单排序算法
    Django学习-25-图片验证码实例
    Django学习-24-Ajax
    Django学习-23-ModelForm
    Django学习-22-Form
    Django学习-21-表关系参数
    Django学习-20-信号
    用"再生龙"Clonezilla 来克隆Linux系统
  • 原文地址:https://www.cnblogs.com/zero-begin/p/4350342.html
Copyright © 2020-2023  润新知