zoukankan      html  css  js  c++  java
  • nlogn求解最长上升子序列

    nlogn求解最长上升子序列

    先讲解两个函数 lower_bound()和upper_bound()

    使用规范为

    lower_bound(数组名+k,数组名+k+n,x,cmp)代表在数组[k]到数组[k+n]中查找x  并可以使用重载重新定义cmp  

    upper_bound(数组名+k,数组名+k+n,x,cmp)代表在数组[k]到数组[k+n]中查找x  并可以使用重载重新定义cmp

    两者的区别在于lower_bound()返回的是非降序列的第一个>=key的地址(指针

    而upper_bound()返回的是非降序列的第一个>key的地址(指针

    1.n方时间复杂度的最长上升子序列

    int maxx=0;
    for
    (int i=1;i<=n;i++)//遍历整个数组的数字 {
       dp[i]=1;
    for(int j=1;j<i;j++)//寻找当前最长的上升子序列长度 { if(num[i]>num[j]) dp[i]=max(dp[i],dp[j]+1);//状态转移方程 dp[i]=max(dp[i],dp[j]+1),代表在第i个数时最长上升子序列的长度 如果有更优解就更新dp数组 }
       maxx=max(dp[i],maxx);//维护一个最大值 }

     2.nlogn时间复杂度求解最长上升子序列

    int len=1;
    num[1]=dp[1];
    for(int i=2;i<=n;i++)//遍历整个数组 寻找上升的序列
    {
        if(dp[i]>num[len]){//如果符合条件 将其放入序列末端  
            num[++len]=dp[i];
        }
        else{//如果不符合条件 通过二分 寻找最后一个小于等于这个数的位置 并替换  因为是替换 所以不会影响总序列长度 
            int p=lower_bound(num+1,num+len+1,dp[i])-num;
            num[p]=dp[i];
        }
    }

    这样优化过后  时间复杂度缩减到 n*logn  既外层循环n 内层logn的时间复杂度

    3.nlogn时间复杂度最长不上升子序列

    struct cmp{
        bool operator()(int a,int b){return a>b;}
    };
    
    
    
    for(int i=2;i<=z;i++){
            if(dp1[len1]>=num[i])
                dp1[++len1]=num[i];
            else{
                int p1=upper_bound(dp1+1,dp1+1+len1,num[i],cmp())-dp1;
                dp1[p1]=num[i];
            }
    }
    人十我百 人百我万
  • 相关阅读:
    解压 Android 系统中的 system.img
    挂载system.img并提取文件
    [android]system.img文件的打包和解包
    linux修改权限
    不懂这个别说是刷机高手!安卓Recovery你知多少
    Android刷机
    eclipse的“sun.misc.BASE64Encoder”问题解决
    spring的multipartResolver和java后端获取的MultipartHttpServletRequest方法对比 (附:遇到的坑)
    《高性能mysql》笔记(第一章,mysql的架构与历史)
    hystrix流程图收藏
  • 原文地址:https://www.cnblogs.com/bestcoder-Yurnero/p/10685932.html
Copyright © 2011-2022 走看看