poj_2533 Longest Ordered Subsequence(最长上升子序列)

来源:互联网 发布:郭正亮 知乎 编辑:程序博客网 时间:2024/05/01 01:34
Longest Ordered Subsequence
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 48278 Accepted: 21489

Description

A numeric sequence of ai is ordered ifa1 <a2 < ... < aN. Let the subsequence of the given numeric sequence (a1,a2, ...,aN) be any sequence (ai1,ai2, ...,aiK), where 1 <=i1 < i2 < ... <iK <=N. For example, sequence (1, 7, 3, 5, 9, 4, 8) has ordered subsequences, e. g., (1, 7), (3, 4, 8) and many others. All longest ordered subsequences are of length 4, e. g., (1, 3, 5, 8).

Your program, when given the numeric sequence, must find the length of its longest ordered subsequence.

Input

The first line of input file contains the length of sequence N. The second line contains the elements of sequence - N integers in the range from 0 to 10000 each, separated by spaces. 1 <= N <= 1000

Output

Output file must contain a single integer - the length of the longest ordered subsequence of the given sequence.

Sample Input

71 7 3 5 9 4 8

Sample Output

4
有O(n^2)和O(nlogn)两种做法。
O(n^2)的做法:dp[i]表示以第i个元素为子序列终点所得的最长上升子序列长度,状态方程:dp[i] = max(dp[j](同时满足a[j]<a[i]))+1
O(nlogn)的做法:用一个数组去保存目前找到的最长子序列,枚举所给的n个元素,如果当前元素大于数组中最后一个元素(即当前子序列最大数),
则将该元素添加到数组后面;如果小于最大数,则二分查找数组中小于该数的元素位置,将该数覆盖到该位置的后面一位,这样能够使得在保持数组单调性的同时,
让较小的数去代替较大的数。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <stack>#include <bitset>#include <queue>#include <set>#include <map>#include <string>#include <algorithm>#define FOP freopen("data.txt","r",stdin)#define FOP2 freopen("data1.txt","w",stdout)#define inf 0x3f3f3f3f#define maxn 1000010#define mod 1000000007#define PI acos(-1.0)#define LL long longusing namespace std;int n;int a[10010];int dp[10010];int main(){    while(~scanf("%d", &n))    {        int ans = 1;        for(int i = 1; i <= n; i++) scanf("%d", &a[i]);        for(int i = 1; i <= n; i++) dp[i] = 1;        for(int i = 2; i <= n; i++)        {            int ma = 0;            for(int j = 1; j < i; j++)                if(ma < dp[j] && a[j] < a[i]) ma = dp[j];            dp[i] = ma + 1;            if(ans < dp[i]) ans = dp[i];        }        printf("%d\n", ans);    }    return 0;}


#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <stack>#include <bitset>#include <queue>#include <set>#include <map>#include <string>#include <algorithm>#define FOP freopen("data.txt","r",stdin)#define FOP2 freopen("data1.txt","w",stdout)#define inf 0x3f3f3f3f#define maxn 1000010#define mod 1000000007#define PI acos(-1.0)#define LL long longusing namespace std;int n;int a[10010];int dp[10010];int main(){    //FOP;    while(~scanf("%d", &n))    {        for(int i = 1; i <= n; i++) scanf("%d", &a[i]);        int len = 1;        dp[1] = a[1];        for(int i = 2, j; i <= n; i++)        {            if(dp[len] < a[i]) j = ++len;            else j = lower_bound(dp+1, dp+len+1, a[i]) - dp;            dp[j] = a[i];        }        printf("%d\n", len);    }    return 0;}


0 0