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\n",lower_bound(dp,dp+n,INF)-dp);
}

 

posted on 2017-03-20 19:39  mkfoy  阅读(251)  评论(0编辑  收藏  举报

导航