hello Hello, everyone, welcome to visit Lin Shen when seen deer blog, algorithms white, recorded bit by bit to learn everyday, dedicated user-friendly solution to a problem, that is met Shangshang, if insufficient, also requested the exhibitions.
table of Contents
1. Title
Given a sequence of length N, find the longest length of the subsequence whose value is strictly monotonically increasing.
Input format The
first line contains the integer N.
The second line contains N integers, representing the complete sequence.
Output format
Output an integer, indicating the maximum length.
Data range
1≤N≤100000,
−109≤Number in the sequence ≤109
Input example:
7
3 1 2 1 8 5 6
Output example:
4
2. Thinking (greedy + dichotomy) O(nlogn)
The simple version of LIS has a time complexity of O(n^2) and will time out, so we use greedy + two points to do this question. Let's
talk about the greedy idea first:
we define an array q[], and let the q array store the minimum value at the end of the ascending subsequence under the same length. Because if we can receive a larger number, then we must be able to receive a smaller number, and after receiving a smaller number, we can leave more space for us to receive other numbers, making the array The length is longer. It can be proved that the q array must be monotonously rising. The length of the last q array is the answer.
Let's talk about two points:
how to update the q array?
We traverse the original a array, and for each a[i], we look for the largest number x less than a[i] in the q[] array. After finding, we update the next number of x to a[i], because x is the largest number less than a[i], then the next number of x must be greater than or equal to a[i]. This also proves that if the last number of x is also less than a[i], then the largest number in the q array that is less than a[i] is not x but the next number of x (array q monotonically rises) , This is the opposite of our dichotomy.
3. Code
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1e5+10;
int a[N];
int q[N];
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
int len=0;
for(int i=0;i<n;i++)
{
int l=0,r=len;
while(l<r) //二分去更新数组q
{
int mid=l+r+1>>1;
if(q[mid]<a[i]) l=mid;
else r=mid-1;
}
q[r+1]=a[i];
len=max(len,r+1);
}
printf("%d\n",len);
return 0;
}