最长上升子序列(LIS)nlogn模板

//最后ans[i]求的是长度为i+1的上升子序列的最小后缀
//答案,也就是长度为len,但是方案却是无法求出来的。 
#include<cstdio>
#include<algorithm>
#include<cstring>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std;

const int MAXN = 112;
int num[MAXN], ans[MAXN], n;

int main()
{
	while(~scanf("%d", &n))
	{
		int len = 0;
		memset(ans, 0, sizeof(ans));
		REP(i, 0, n) scanf("%d", &num[i]);
		
		ans[0] = num[0];
		REP(i, 1, n)
		{
			if(num[i] > ans[len]) ans[++len] = num[i];
			else ans[lower_bound(ans, ans+len, num[i]) - ans] = num[i]; //这里lower_bound的范围是没用最后一个元素的 
		}                                                               //但是没有关系,一样可以返回最后一个元素的位置 
		printf("%d\n", len + 1); //一开始len是从0开始,最后记得加回1 
	}
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_34416123/article/details/81358447