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 }
  • 相关阅读:
    vue组件详解(四)——使用slot分发内容
    vue组件详解(三)——组件通信
    vue组件详解(二)——使用props传递数据
    vue组件详解(一)——组件与复用
    vue表单详解——小白速会
    vue class与style 绑定详解——小白速会
    vue内置指令详解——小白速会
    vue计算属性详解——小白速会
    SQL查询当天、本周、本月记录详解
    SQL Server中使用convert进行日期转换
  • 原文地址:https://www.cnblogs.com/sykline/p/9737856.html
Copyright © 2011-2022 走看看