zoukankan      html  css  js  c++  java
  • LIC

    问题描述:

    一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的。对于给定的一个序列(a1, a2, ..., aN),我们可以得到一些上升的子序列(ai1, ai2, ..., aiK),这里1 <= i1 < i2 < ... < iK <= N。比如,对于序列(1, 7, 3, 5, 9, 4, 8),有它的一些上升子序列,如(1, 7), (3, 4, 8)等等。这些子序列中最长的长度是4,比如子序列(1, 3, 5, 8).

    你的任务,就是对于给定的序列,求出最长上升子序列的长度。

    解法1:

    时间复杂度O(n^2);

     1 /*
     2 dp[i]:以a[i]结尾的字符串长度;
     3 有两种可能性;
     4 1.只包含a【i】
     5 2.附加到j<i&&a[j]<a[i],那么dp[i]=max(dp[j]+1,dp[i])
     6 */
     7 
     8 #include <iostream>
     9 #include <cstdio>
    10 #include <cstring>
    11 using namespace std;
    12 
    13 const int MAXN=100000;
    14 const int INF=1<<30;
    15 
    16 int a[MAXN];
    17 int dp[MAXN];  //代表以a【i】为结尾的序列的长度。
    18 
    19 int main(){
    20     int n;  //代表序列的个数
    21     while(scanf("%d",&n)!=EOF){
    22         for(int i=0;i<n;i++)
    23             scanf("%d",&a[i]);
    24 
    25         memset(dp,0,sizeof(dp));
    26 
    27         int ans=-INF;
    28         for(int i=0;i<n;i++){
    29             dp[i]=1;  //这是只有a[i];
    30             for(int j=0;j<i;j++)
    31                 if(a[j]<=a[i])
    32                     dp[i]=max(dp[j]+1,dp[i]);
    33             ans=max(ans,dp[i]);
    34 
    35         }
    36         cout<<ans<<endl;
    37     }
    38 }

    方法二:

    时间复杂度:O(nlgn)

    /*
    dp[i]:长度为i+1的上升子序列中末尾的最小值:
    很明显长度i的子序列,其dp【i]越小,其在后面越占优势,而如何来更新dp【i】的值呢
    上面一个算法,在查找的浪费了大量的时间,
    这儿的dp数组的值明显是单调递增的。可以用二分搜索来查找,就可以把整个算法的时间复杂度,降低为O(nlgn);
    */
    
    int bSearch(int num, int k)  
    {  
        int low=1, high=k;  
        while(low<=high)  
        {  
            int mid=(low+high)/2;  
            if(num>=dp[mid])  
                low=mid+1;  
            else   
                high=mid-1;  
        }  
        return low;  
    }  
     
    int LIS()
    {
        int low = 1, high = n;
        int k = 1;
        dp[1] = a[1];
        for(int i=2; i<=n; ++i)
        {
            if(a[i]>dp[k])
                dp[++k] = a[i];
            else
            {
                int pos = bSearch(a[i], k);
                dp[pos] = a[i];
            }
        }
        return k;
    }
    
    void solve(){
        fill(dp,dp+n,INF);
        for(int i=0;i<n;i++)
            *lower_bound(dp,dp+n,a[i])=a[i];   //这是找到dp[i]>=a[i]的最小只真
        printf("%d
    ",lower_bound(dp,dp+n,INF)-dp);
    }
    自己选的路,跪着也要把它走完------ACM坑
  • 相关阅读:
    Stanford机器学习笔记-10. 降维(Dimensionality Reduction)
    Stanford机器学习笔记-9. 聚类(K-means算法)
    Stanford机器学习笔记-8. 支持向量机(SVMs)概述
    Stanford机器学习笔记-7. Machine Learning System Design
    Stanford机器学习笔记-6. 学习模型的评估和选择
    Stanford机器学习笔记-5.神经网络Neural Networks (part two)
    k sum 问题系列
    正则表达式
    Manacher算法--O(n)回文子串算法
    leetcode难度及面试频率
  • 原文地址:https://www.cnblogs.com/IKnowYou0/p/6591200.html
Copyright © 2011-2022 走看看