CF340D Bubble Sort Graph&&Acwing896. 最长上升子序列 II

题意

给你一个长度为n的序列,求这个序列的最长上升子序列的长度
n<=100000

先说一下朴素的动态规划

即设\(f[i]\)表示以\(i\)为结尾的,最长上升子序列的长度

状态转移

\(if(a[j]<a[i]) f[i]=max(f[i],f[j]+1)\)

可以看出,朴素的动态规划我们的时间复杂度是\(O(n^2)\)

时间复杂度肯定过不去,那么我们考虑怎么优化

不难发现,一个数会产生贡献,仅当它排在一个比它小的数后面,

我们可以开一个栈来维护

当这个新加进去的这个数比栈顶的元素小时,我们直接加进去

否则我们贪心的想,为了让其最长,小的数用的越多越好

所以我们就二分查找一下这个比较小的数可以放在哪里

将比它大的那个替换掉就好

时间复杂度\(O(nlogn)\)

代码

#include<bits/stdc++.h>
using namespace std;
const int N=200000;
vector<int>arr(N);
int n,a[N];
int main()
{
	cin>>n;
	for(int i=1; i<=n; i++)
		cin>>a[i];
	arr.push_back(a[1]);
	for(int i=2; i<=n; i++)
	{
		if(a[i]>arr.back())
			arr.push_back(a[i]);
		else {
			*lower_bound(arr.begin(),arr.end(),a[i])=a[i];
		}
	}
	cout<<arr.size()<<endl;
}
/*
例 n: 7
arr : 3 1 2 1 8 5 6

stk : 3

1 比 3 小
stk : 1

2 比 1 大
stk : 1 2

1 比 2 小
stk : 1 2

8 比 2 大
stk : 1 2 8

5 比 8 小
stk : 1 2 5

6 比 5 大
stk : 1 2 5 6

stk 的长度就是最长递增子序列的长度

*/

posted @ 2020-11-20 17:39  邦的轩辕  阅读(86)  评论(0编辑  收藏  举报