最长上升子序(lis)

    xiaoxiao2025-05-30  98

    最长上升子序 通常 有两种写法

    第一种 就是 朴素求法 时间复杂度为O(n2)         用 朴素求法 时,数据稍微 好一点,都会超时 所以 一般不会用它 去做题 进入正题 :           第二种求法 则将时间复杂度优化到O(nlogn)

    #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int a[100005]; int lis[100005]; //用来存 上升 序列 int main() { int n; int count = 1; scanf( "%d",&n); memset(a,0,sizeof(a)); memset(lis,0,sizeof(lis)); for(int i = 1;i <= n;i++) scanf("%d",&a[i]); lis[count] = a[1]; //将 第一个数 存进 s 数组 // 因为 每操作 一次 的结果都是 最长 且 最小 的子序列,所以 是不会漏掉 任何一个数的 for(int i = 2;i <= n;i++) // 第一个数已经判断过 { if(a[i] > lis[count]) //如果a[i] > lis 的最后一个数字,就将 a[i] 存进 lis 数组 { //如果要求 最长 不下降子序 则 将 这里 > 换成 >= 即可 count++; lis[count] = a[i]; } else { //lower_bound 内部是用 二分 实现的 int temp = lower_bound(lis + 1,lis + count + 1,a[i]) - lis;// 在lis中 找到 第一个大于等于a[i]的 地址 lis[temp] = a[i]; // 将 找到的这个数 替换为 a[i] } //所以最后 lis 数组存放的也就是 最长 且 最小 的上升子序列 } printf("%d\n",count); return 0; }
    最新回复(0)