zoukankan      html  css  js  c++  java
  • 51nod1134最长递增子序列(二分)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=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示例
    8
    5
    1
    6
    8
    2
    4
    5
    10
    Output示例
    5

    一开始我是用dp写的,本来以为就是一道模板题,发现超时了,时间复杂度是o(n2),先贴下超时的代码
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int a[50005],dp[50005];
    int main()
    {
        int n,ans=0;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        for(int i=0;i<n;i++)
        {
            dp[i]=1;
            for(int j=0;j<i;j++)
            {
                if(a[i]>a[j])
                    dp[i]=max(dp[i],dp[j]+1);    
            }
            ans=max(ans,dp[i]);
        }
        printf("%d
    ",ans);
        return 0;
    } 

    之后看了博客才知道要用二分,这样时间复杂度就只有o(nlogn),要用len记录一下当前最长子序列的数量,这里用到了

    二分查找的函数lower_bound(),这个函数有三个参数lower_bound(f,f+len,a[i]),f和f+len是指针,就是在f到f+len二分查找a[i]放置的位置,返回的也是指针,不会可以百度下。

    代码:

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int a[50005];
    int f[50005];
    int main()
    {
        int n,maxn;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
               scanf("%d",&a[i]);
        int len=1;
        memset(f,0,sizeof(f));//创建一个新数组存放最长上升序列
        f[0]=a[0];
        for(int i=1;i<n;i++) 
        {
           int pos=lower_bound(f,f+len,a[i])-f;//二分查找i+1个数中最长上升序列,a[i]的位置 
           f[pos]=a[i];
           /*cout<<ans<<" "<<pos<<endl;*/
           len=max(len,pos+1);//最长上升序列的数量 
        }
        /*for(int i=0;i<ans;i++)
            cout<<f[i]<<endl;*/
        printf("%d
    ",len);
        return 0;
    }
     
  • 相关阅读:
    【足迹C++primer】46、动态存储类
    java foreach循环为什么不能赋值
    使用apktool解包和打包apk
    杭电 HDU ACM Milk
    [SQL基础]入门
    [c#基础]泛型集合的自定义类型排序
    [Asp.net]常见word,excel,ppt,pdf在线预览方案,有图有真相,总有一款适合你!(续)
    [c#基础]使用抽象工厂实现三层
    [c#基础]DataTable的Select方法
    Winform模拟post请求和get请求登录网站
  • 原文地址:https://www.cnblogs.com/xiongtao/p/9293951.html
Copyright © 2011-2022 走看看