POJ 2533 Longest Ordered Subsequence(LIS)

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;
}

你可能感兴趣的:(POJ 2533 Longest Ordered Subsequence(LIS))