当前位置: 代码迷 >> 综合 >> HDU1950[Bridging signals] LIS模型 (nlogn)
  详细解决方案

HDU1950[Bridging signals] LIS模型 (nlogn)

热度:77   发布时间:2023-11-06 08:22:07.0

最长上升子序列(LIS) nlogn方法


a[]数组存原序列

ans[] 第i位 表示 长度为 i 的 上升子序列的结尾 最小为 ans[i]

a[]={4,2,6,3,1,5} len为最长上升子序列长度

模拟过程:

先 ans[1]=a[1]. ans={4} len=1

a[2]=2, 2 小于 ans[len] ,即 2 < 4 , 所以 2可以替换4。 ans={2}, len=1

a[3]=6, 6 大于 ans[len] , 即 6 > 2, 所以6可以加入上升序列 ans[++len]=6, ans={2,6}, len=2

a[4]=3, 3<6并且 3>2,显然,应该用3替换2 所以 ans[len]=3, ans={2,3} len=2

a[5]=1, 1<2 所以 1 替换 2, ans[1]=1, ans={1,3} len=2

a[6]=5, 5>3 所以 5 加入序列 ans[++len]=5, ans={1,3,5}, len=3

最长上升子序列长度为3

算法流程:

定义 原数组 a, 答案数组 b
枚举 a 数组中的每个元素
如果大于b的最后一个元素
当前元素加入 b
答案长度+1
否则
二分查找 a当前元素 替换 b 中的位置
替换 b 中 的 元素


题目链接


题意:求给出序列的最长上升子序列

#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
vector<int> a, ans;
vector<int>::iterator t; 
int main(){int n, T;scanf("%d", &T );while( T-- ){a.clear(); ans.clear();scanf("%d", &n );for ( int i=1, x=0; i<=n; i++ ) scanf("%d", &x ), a.push_back(x);ans.push_back(a[0]);for ( int i=1; i<a.size(); i++ ){if( a[i]>ans[ans.size()-1] ) ans.push_back(a[i]);else {t=lower_bound(ans.begin(), ans.end(),a[i]);*t=a[i];}}printf("%d\n", ans.size() );}
} 
  相关解决方案