最长递增子序列模板(原版+二分优化)

比较简单,用下面那个例子模拟一下就知道了

#include <iostream>
using namespace std;

const int N = 10000;

int a[N],dp1[N],dp2[N];

int LIS_1(int n){
	
	int ans = 0;
	
	for(int i = 1; i <= n; i++){
		
		int k = 0;
		
		for(int j = 1;j<i;j++)//遍历前面每一个可能
			if(a[j] < a[i] && k < dp1[j]) k = dp1[j];
		
		dp1[i] = k + 1; //找到前面小于当前元素的最大值再加上当前数 
		
		if(ans < dp1[i]) ans = dp1[i];//求最大递增序列非连续的。。 
	}
	return ans;
} 

int BinarySearch(int i,int j,int k){	//找第一个大于k的数 
	
	while(i < j){
		
		int mid = (i+j) / 2;
		if(a[mid] > k)	 
			j = mid;
		else
			i = mid+1;
	}
	
	return j;

}

int LIS_2(int n){
	
	int index = 0;
	dp2[++index] = a[1];
	//通过dp数组来储存一个递增序列,dp的下标就是序列长度 
	for(int i = 2;i<=n;i++){
		
		if(a[i] > dp2[index]){
			dp2[++index] = a[i];
		}else{
			
			int pos = BinarySearch(1,index,a[i]);
			dp2[pos] = a[i];
		}
	}
	return index; 
}


int main(){
	
	int n;
	cin >> n;
	
	
	for(int i = 1;i<=n;i++) cin >> a[i]; 
	
	cout << LIS_1(n) << endl;	//原版 
	
	cout << LIS_2(n) << endl;	//优化 
	
	return 0;
}

/*
8
65 158 170 155 239 300 207 389

*/
上一篇:题解 HDU5834 【Magic boy Bi Luo with his excited tree】


下一篇:[NOIP1999]拦截导弹