E04 线性DP 最长上升子序列 二分优化

视频链接:https://www.bilibili.com/video/BV1Kp4y1e77H/

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=100010;
int n, a[N];
int len, b[N]; //记录上升子序列

int main(){
  scanf("%d", &n);
  for(int i=0; i<n; i++) scanf("%d", &a[i]);

  b[0]=-2e9;                              //哨兵
  for(int i=0; i<n; i++)
    if(b[len]<a[i]) b[++len]=a[i];        //新数大于队尾数,则插入队尾
    else *lower_bound(b,b+len,a[i])=a[i]; //替换第一个大于等于a[i]的数(贪心)

  printf("%d\n", len);
}
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=100010;
int n, a[N];
int len, b[N];  

int find(int x){
  int l=-1, r=len;
  while(l+1<r){    
    int mid=l+r>>1;
    if(b[mid]>=x) r=mid;
    else l=mid;
  }
  return r;
}
int main(){
  scanf("%d", &n);
  for(int i=0; i<n; i++) scanf("%d", &a[i]);

  b[0]=-2e9;
  for(int i=0; i<n; i++){
    if(b[len]<a[i]) b[++len]=a[i];
    else b[find(a[i])]=a[i];
  }

  printf("%d\n", len);
}

 

posted @ 2023-04-09 22:25  董晓  阅读(629)  评论(1编辑  收藏  举报