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;
}
目录
相关文章
|
算法 JavaScript Go
【动态规划】最长递增子序列
【动态规划】最长递增子序列
|
10月前
|
算法 程序员 C#
C++二分查找算法的应用:最长递增子序列
C++二分查找算法的应用:最长递增子序列
|
12月前
|
算法
【学会动态规划】最长递增子序列的个数(28)
【学会动态规划】最长递增子序列的个数(28)
39 0
|
12月前
|
算法
【学会动态规划】 最长递增子序列(26)
【学会动态规划】 最长递增子序列(26)
36 0
|
算法 Java 测试技术
dp算法 力扣152乘积最大子数组
dp算法 力扣152乘积最大子数组
|
人工智能
(闫氏dp分析法)(线性dp)(区间类dp)AcWing 895. 最长上升子序列
(闫氏dp分析法)(线性dp)(区间类dp)AcWing 895. 最长上升子序列
89 0
|
存储 人工智能
【动态规划】LIS最长上升子序列【入门】
【动态规划】LIS最长上升子序列【入门】
93 0
|
人工智能 C++
牛妹爱数列(动态规划 dp)
牛妹正在玩一个数列,他手里有一个长度为n的序列a,保证它是一个01序列,并执行以下两种操作:1.单点修改:将位置x上的数翻转(0变1,1变0);2.前缀修改:将位置1~x上的数翻转(每个数都0变1,1变0)。他现在想要最小化翻转次数,使得数列上的所有数都变为0。
牛妹爱数列(动态规划 dp)