POJ2533 Longest Ordered Subsequence(最長遞增子序列)

Longest Ordered Subsequence
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 38934   Accepted: 17094

Description

A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given numeric sequence (a1a2, ..., aN) be any sequence (ai1ai2, ..., 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

7
1 7 3 5 9 4 8

Sample Output

4

題意:長度爲n的數列,求最長遞增子序列的長度。

法一:動態規劃,時間複雜度O(N²):

dp[i]表示以第i個爲結尾的數列的最長子序列長度,等於該數之前的最長子序列(該數大於子序列的最大數)的長度加一。

#include <cstdio>
#include <iostream>
#include <algorithm>

using namespace std;

int a[1005],dp[1005];

int main()
{
    int n,maxn,ans;
    while(scanf("%d",&n) != EOF) {
            ans = 0;
        for(int i = 0; i < n; i++) {
            scanf("%d",&a[i]);
            maxn = 0;
            for(int j = 0; j < i; j++)
            {
                if(dp[j] > maxn && a[i] > a[j])
                    maxn = dp[j];
            }
            dp[i] = maxn + 1;
            ans = max(ans, dp[i]);
        }
        printf("%d\n",ans);
    }
}

法二:時間複雜度O(NlogN):

每輸入一個值,用二分查找找到它的位置,頂替該位置的數,保持數列遞增。最後得到的數列長度就是最長子序列長度,但不是最長子序列。

#include <cstdio>
#include <iostream>
#include <algorithm>

using namespace std;

int a[1005],n,num,ans,p;

int erfen(int num, int a[])
{
    int l = 0, r = n, mid;
    while(l < r) {
        mid = (l + r) >> 1;
        if(num <= a[mid])
            r = mid;
        else if(num > a[mid])
            l = mid + 1;
    }
    return r;
}

int main()
{
    while(scanf("%d",&n) != EOF) {
        for(int i = 0; i < 1005; i++)
            a[i] = 10005;
        for(int i = 0; i < n; i++) {
            scanf("%d",&num);
            p = erfen(num,a);
            if(a[p] == 10005)
                ans ++;
            a[p] = num;
        }
        printf("%d\n",ans);
    }
}


發佈了39 篇原創文章 · 獲贊 1 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章