LIS

朴素法:

//ans数组为待查询数组
void lis(int n){
    int num[n+1];
    for(int i=1;i<=n;++i)  num[i]=1;//num[i]表示从1到i的最长上升子序列的长度 
    for(int i=1;i<=n;++i){//每次加入一个ans[i],就扫描ans[1]到ans[i-1],如果ans[i]大于他们,那么num[i]就等于他们的最大长度加一,然后取最大值 
        for(int j=1;j<i;++j){
            if(ans[i]>ans[j]){
                num[i]=max(num[j]+1,num[i]);
            }
        }
    }
    for(int i=1;i<=n;++i){//找最大 
        mx=max(mx,num[i]);
    }
}

nlogn:二分

//ans数组为待排序数组
void lis(int n){
    int num[n+1];//维护一个有序数组num,最后num的长度即是最大上升子序列的长度 
    num[1]=ans[1] ;
    int len=1;
    for(int i=2;i<=n;++i){
        if(ans[i]>num[len]){
            num[++len]=ans[i];
        }
        else{//当前的ans[i]大于有序数组num的最大值 
            //从num数组中找到第一个大于等于ans[i]的数的位置 
            int tmp=lower_bound(num+1,num+len+1,ans[i])-num;
            //将找到的位置的值换成ans[i],此时num依然有序 
            num[tmp]=ans[i];
        } 
    }
/*
列如序列:1,2,6,4,5
当n从1到3时原序列上升,对应的num数组从1到n等于ans 即1,2,6
 n==4  tmp=3   num[3]=ans[i]=4  此时num数组:1,2,4   len=3
 n==5  ans[5] =5>num[len]=4   num[5]=5   此时num数组:1,2,4,5  len=4
 ********
 这种方法并不能求出最长上升子序列本身,只能求长度
 例如原序列:1  2   4  5  3
 按此方法求出的是1  2  3  5 ,答案应该是1 2 4 5 
*/
    mx=len; 
}
全部评论

相关推荐

牛客316659795号:不是,证明hr初筛已经过了,要投给部门筛一遍
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务