51NOD 最长递增子序列(模板)

来源:互联网 发布:书生软件安卓 编辑:程序博客网 时间:2024/06/02 11:16
1134 最长递增子序列
给出长度为N的数组,找出这个数组的最长递增子序列。(递增子序列是指,子序列的元素是递增的)
例如:5 1 6 8 2 4 5 10,最长递增子序列是1 2 4 5 10。
 
Input
第1行:1个数N,N为序列的长度(2 <= N <= 50000)第2 - N + 1行:每行1个数,对应序列的元素(-10^9 <= S[i] <= 10^9)
Output
输出最长递增子序列的长度。
Input示例
8516824510
Output示例
5

O(n^2)  TLE

#include <iostream>  TLE#include <cstring>#define N 50010using namespace std;int num[N],dp[N];int main(){    cin.sync_with_stdio(false);    int n;    while(cin>>n){        for(int i=0;i<n;i++){            cin>>num[i];            dp[i]=1;        }        for(int i=1;i<n;i++){            for(int j=0;j<i;j++){                if(num[i]>num[j]){                    dp[i]=max(dp[i],dp[j]+1);                }                }        }        int mmax=dp[0];        for(int i=1;i<n;i++){            mmax=max(mmax,dp[i]);        }        cout<<mmax<<endl;    }    return 0;}

 

O(N*logN)

#include <iostream>#include <cstring>#define N 50010using namespace std;int num[N],dp[N];int BiSearch(int len,int key){//二分法    int l=0,r=len-1;    while(l<=r){        int mid=(l+r)/2;        if(dp[mid]>key){            r=mid-1;        }        else if(dp[mid]<key){            l=mid+1;        }        else{            return mid;        }    }    return l;}int main(){    cin.sync_with_stdio(false);    int n;    while(cin>>n){        for(int i=0;i<n;i++){            cin>>num[i];        }        int len=1;        dp[0]=num[0];        for(int i=1;i<n;i++){            if(num[i]>dp[len-1]){                dp[len]=num[i];                len++;            }            else{                int pos=BiSearch(len,num[i]);                dp[pos]=num[i];            }        }        cout<<len<<endl;    }    return 0;}

推荐一篇好的讲解博客:传送门 

2016-12-10 16:43:12