最长上升子串

来源:互联网 发布:ubuntu 系统语言安装 编辑:程序博客网 时间:2024/05/12 03:34

最长上升字串:

介绍一个n*logn的解法:使用二分,代码简短:
根据dp,dp[i] 表示:长度为i+1的上升子序列中末尾元素的最小值,默认表示的INF,若出现比当前还小的元素,则进行更新操作,dp数列除了INF都是单调递增的,所以对于每次操作,需要更新的位置则不需要全都遍历,只需要使用二分搜索进行判断,时间复杂度为nlogn。
#include <iostream>#include <algorithm>using namespace std;const int  MAX = 100;int dp[MAX];int a[MAX];int n;const int INF = 1<<30;void slove(){    //lower_bound:表示返回指向a[i]的最小指针位置,不存在就返回第一个不小于a[i]的元素位置    fill(dp,dp+n,INF);    for(int i=0;i<n;i++)        *lower_bound(dp,dp+n,a[i]) = a[i];    cout<<(lower_bound(dp,dp+n,INF)-dp)<<endl;}int main(){    cin>>n;    for(int i=0;i<n;i++)            cin>>a[i];    slove();    return 0;}

使用了lower_bound算法。
#include <iostream>using namespace std;const int  MAX = 100;int dp[MAX];int a[MAX];int n;int search(int num,int low,int high){    int mid;    while(low<=high){        mid = low+((high-low)>>1);//(low+high)/2;        if(num>=dp[mid])            low = mid+1;        else            high = mid-1;    }    return low;}int DP(){    int len=0,pos;    dp[0]=a[0];    for(int i=1;i<n;i++){        if(a[i]>=dp[len]){            len = len+1;            dp[len] = a[i];        }else{            pos = search(a[i],0,len);            dp[pos] = a[i];        }    }    cout<<len+1<<endl;    return len+1;}int main(){    cin>>n;    for(int i=0;i<n;i++)            cin>>a[i];    DP();    return 0;}
同样的实现,代码相对复杂。

0 0
原创粉丝点击