LIS(最长递增子序列) 二分 + dp

简介: 笔记

算法:动态规划+二分查找

时间复杂度:O(nlogn)

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define mod 998244353
#define endl '\n'
using namespace std;
typedef long long LL;
typedef pair<int, int>PII;
const int N = 100010;
int n;
int a[N], q[N];
// q[i] 表示长度为 i 的上升子序列的末尾元素最小为 q[i]
void solve() {
  cin >> n;
  for (int i = 1; i <= n; ++i) scanf("%d", a + i);
  int len = 0;
  for (int i = 1; i <= n; ++i) { //对于每个数 找到最后一个比它小的数对应的长度
    int l = 0, r = len;
    while (l < r) {
      int mid = l + r + 1>> 1;
      if (q[mid] < a[i])l = mid;
      else r = mid - 1;
    }
    // 可以把当前这个数放在长度为 r 的上升子序列后面 所以长度为 r + 1
    len = max(len, r + 1); 
    //因为找到的是 小于 a[i] 的上升子序列的长度最大值 所以 q[r + 1] 一定比 a[i] 大 那么更新 q[r + 1] 为 a[i] 不会改变长度 且后续有更多的空间放后面的数
    q[r + 1] = a[i]; 
  }
  printf("%d\n", len);
}
int main() {
  //int t; cin >> t;
  //while (t--)
    solve();
  return 0;
}
目录
相关文章
|
11月前
|
算法 程序员 C#
C++二分查找算法的应用:最长递增子序列
C++二分查找算法的应用:最长递增子序列
|
算法
【学会动态规划】最长递增子序列的个数(28)
【学会动态规划】最长递增子序列的个数(28)
46 0
|
算法 Java 测试技术
dp算法 力扣152乘积最大子数组
dp算法 力扣152乘积最大子数组
|
算法
LeetCode 周赛 347(2023/05/28)二维空间上的 LIS 最长递增子序列问题
这场周赛是 LeetCode 第 347 场单周赛,T4 是结合 LIS 最长递增子序列的动态规划问题。
83 0
|
机器学习/深度学习 人工智能
51nod 1055 最长等差数列 (dp好题)
51nod 1055 最长等差数列 (dp好题)
51 0
|
人工智能
(闫氏dp分析法)(线性dp)(区间类dp)AcWing 895. 最长上升子序列
(闫氏dp分析法)(线性dp)(区间类dp)AcWing 895. 最长上升子序列
102 0
leetcode 673 最长递增子序列的个数
leetcode 673 最长递增子序列的个数
76 0
|
存储
Leetcode | 673. 最长递增子序列的个数
Leetcode | 673. 最长递增子序列的个数
136 0
Leetcode | 673. 最长递增子序列的个数