最长上升子序列 【二分查找】
题意:给定一个无序的整数数组,找到其中最长的上升子序列的长度。
思路一:动态规划:dp[i]=max{dp[k]+1} (num[i]>num[k],0<=k<i)
时间复杂度为O(n*n)
思路二:动态规划+二分搜索
用dp数组存放当前最长上升子序列,使用二分搜索查询下一个元素在当前最长上升子序列中的位置,并更新该位置的元素值,若下一个元素插入点为当前最长上升子序列中的最后一个节点,则最长上升子序列长度+1。时间复杂度为O(nlogn)
代码如下:
#include <iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
int n;
cin>>n;
vector<int> num(n+5);
vector<int> dp;
for(int i=0;i<n;i++){
cin>>num[i];
}
int len=1;
dp.push_back(num[0]);
for(int i=1;i<n;i++){
int d=lower_bound(dp.begin(),dp.end(),num[i])-dp.begin();
if(d<=0){
d=0;
dp[d]=num[i];
}
else if(d==len){
len++;
dp.push_back(num[i]);
}
else{
dp[d]=num[i];
}
}
cout<<len<<endl;
return 0;
}