Description
求一数列的最长上升子序列
Input
第一行为数列长度n,第二行为n个整数
Output
输出数列的最长上升子序列长度
Sample Input
7
1 7 3 5 9 4 8
Sample Output
4
Solution
最长升序子序列一般有两种解法,一种是经典的动态规划方法,复杂度为O(n^2),另外一种方法则借助栈和二分查找,复杂度为O(nlgn)。动规解法前面提到过,这里解释下栈和二分查找,这种方法很直观,比较好理解,用一句话说就是顺次扫描数组,如果a[i]大于栈顶的元素则入栈,否则在栈中找到第一个大于a[i]的元素t并用a[i]替换t,最后的top就是最长升序子序列的长度。
Code
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
#define INF (1<<29)
#define maxn 100000
int n;
int a[maxn];
int dp[maxn];
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
fill(dp,dp+n,INF);
for(int i=0;i<n;i++)
*lower_bound(dp,dp+n,a[i])=a[i];
printf("%d\n",lower_bound(dp,dp+n,INF)-dp);
}
return 0;
}