zoukankan      html  css  js  c++  java
  • 【noi 2.6_1759】LIS 最长上升子序列(DP,3种解法)

    题意我就不写了。解法有3种:

    1.O(n^2)。2重循环枚举 i 和 j,f[i]表示前 i 位必选 a[i] 的最长上升子序列长度,枚举a[j]为当前 LIS 中的前一个数。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 using namespace std;
     6 
     7 const int N=1010;
     8 int a[N],f[N];
     9 
    10 int mmax(int x,int y) {return x>y?x:y;}
    11 int main()
    12 {
    13     int n,ans=0;
    14     scanf("%d",&n);
    15     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    16     for (int i=1;i<=n;i++)
    17     {
    18       f[i]=1;
    19       for (int j=1;j<i;j++)
    20         if (a[i]>a[j]) f[i]=mmax(f[i],f[j]+1);
    21       ans=mmax(ans,f[i]);
    22     }
    23     printf("%d",ans);
    24     return 0;
    25 }
    View Code 1

    2.O(n log n)。继正确但不高效的解法后,我们想要对时间复杂度降维。最常见的做法就是二分查找,这题就是把解法1的 j 的O(n)枚举变为O(log n)的二分。那么二分的范围肯定要包含当前的 LIS 的数,而且要知道这些数对应的 f[ ]值。因此,我们只能保存扫完前 i 个选出的最优的 LIS,上述2个条件都可以满足。同时不断扩大和更新(存尽量小的数)这个序列。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 using namespace std;
     6 
     7 const int N=1010;
     8 int a[N],f[N];
     9 
    10 int ffind(int l,int r,int x)
    11 {
    12     if (l==r) return l;
    13     int mid=(l+r)>>1;
    14     if (x>f[mid]) return ffind(mid+1,r,x);
    15     else return ffind(l,mid,x);
    16 }
    17 int main()
    18 {
    19     int n,ans=0;
    20     scanf("%d",&n);
    21     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    22     f[++ans]=a[1];
    23     for (int i=2;i<=n;i++)
    24     {
    25       int x;
    26       if (a[i]>f[ans]) x=++ans;
    27       else x=ffind(1,ans,a[i]);
    28       f[x]=a[i];
    29     }
    30     printf("%d",ans);
    31     return 0;
    32 }
    View Code 2

    3.O(n log n)。(参考自蓝书 p62,挖了坑,没时间填了......)

    1 for (int i=1;i<=n;i++) g[i]=INF;
    2 for (int i=0;i<n;i++)
    3 {
    4     int k=lower_bound(g+1,g+n+1,A[i])-g;
    5     d[i]=k;
    6     g[k]=A[i];
    7 }
  • 相关阅读:
    利用ssh传输文件
    linux 终端常用快捷键
    ubuntu 下关闭apache服务自动启动
    linux ps命令介绍
    virtualenv 使用
    startuml 2.6注册
    三代组装小基因组研究综述
    畅想未来的测序
    测序简史
    纳米孔测序技术介绍
  • 原文地址:https://www.cnblogs.com/konjak/p/5906191.html
Copyright © 2011-2022 走看看