zoukankan      html  css  js  c++  java
  • LIS(两种方法求最长上升子序列)

    首先得明白一个概念:子序列不一定是连续的,可以是断开的。

    有两种写法:

    一、动态规划写法

    复杂度:O(n^2)

    代码:

     1 #include <iostream>
     2 #include <queue>
     3 #include <cstdio>
     4 #include <algorithm>
     5 #include <cmath>
     6 #include <cstring>
     7 #define INF 0x3f3f3f3f
     8 
     9 using namespace std;
    10 typedef long long ll;
    11 const int maxn = 1000;
    12 int a[maxn],dp[maxn];
    13 
    14 int main()
    15 {
    16     ios::sync_with_stdio(false);
    17     int n;
    18     while(cin>>n && n)
    19     {
    20         for(int i = 0; i<n; i++)
    21             cin>>a[i];
    22         int mmax = -1;
    23         for(int i = 0; i<n; i++)
    24         {
    25             dp[i] = 1;
    26             for(int j = 0; j<i; j++)//遍历之前的每一个元素pre
    27             {
    28                 if(a[j]<a[i] && (dp[j]+1>dp[i]))//如果元素pre < 当前元素cur,而且pre的长度+1要比当前的长度多就更新当前的长度
    29                 {
    30                     dp[i] = dp[j]+1;
    31                 }
    32             }
    33             mmax = max(mmax,dp[i]);//维护最大的长度
    34         }
    35         printf("%d
    ",mmax);
    36     }
    37     return 0;
    38 }

    二、low_bound写法

    复杂度:O(nlogn)

    这种写法就是将动规写法中的第二层的遍历改为了二分查找。所以复杂度变为O(nlogn)

    牛客讲解视频

    该算法中开了一个辅助数组h来表示该长度下最后的元素的最小值。例如 1、2、0、5 、-1

    为什么要修改h数组里边的数为小的值呢,因为修改后h数组能变长的潜力就增大了,所以要修改。

    代码:

     1 #include <iostream>
     2 #include <queue>
     3 #include <cstdio>
     4 #include <algorithm>
     5 #include <cmath>
     6 #include <cstring>
     7 #define INF 0x3f3f3f3f
     8 
     9 using namespace std;
    10 typedef long long ll;
    11 const int maxn = 1000;
    12 int a[maxn],dp[maxn];
    13 
    14 int main()
    15 {
    16     ios::sync_with_stdio(false);
    17     int n;
    18     while(cin>>n)
    19     {
    20         memset(a,0,sizeof(a));
    21         for(int i = 0; i<n; i++)
    22             dp[i] = INF;
    23         for(int i = 0; i<n; i++)
    24             cin>>a[i];
    25         int mmax = -1;
    26         for(int i = 0; i<n; i++)
    27         {
    28             int k = lower_bound(dp, dp+n, a[i])-dp;
    29             dp[k] = a[i];
    30             mmax = max(mmax, k+1);
    31         }
    32         printf("%d
    ",mmax);
    33     }
    34     return 0;
    35 }
  • 相关阅读:
    一些python练习题
    爬取某房源网数据
    练习1:定义 is_Even 函数,传一 int 参数,判断是否是偶数,return True;不是,return False
    pycharm中tkinter 不显示窗口
    保护眼睛颜色的RGB数值
    Python study----------class的实例化
    HTML----------STUDY
    Python study----------字典 popitem()
    Python study----------Python搜索路径
    Python study----------第三方module-----chardet(识别编码)
  • 原文地址:https://www.cnblogs.com/sykline/p/9737856.html
Copyright © 2011-2022 走看看