POJ 3903 Stock Exchange [Longest Ascending Subsequence] Template Question

Problem link: http://poj.org/problem?id=3903

Reprinted in: https://www.cnblogs.com/GodA/p/5180560.html

 

Topic meaning:

Naked DP longest ascending subsequence, give you a sequence, find the length of its longest ascending subsequence, n^2 dp naive algorithm can not pass, here is the nlogn algorithm, using binary search.

 

Analysis of specific algorithm ideas:

In the learning dynamic programming problem (DP problem), there is a knowledge point called the longest increasing subsequence, which can also be called the longest non-descending subsequence, or LIS for short. Just tell me what you think.

  We all know that a characteristic of dynamic programming is that the current solution can be derived from the solution of the previous stage, thereby reducing the problem we require into a smaller sub-problem. The subproblems are solved in the same way, but on a smaller scale. The longest ascending subsequence fits this property. We require the longest ascending subsequence of n numbers, and we can find the longest ascending subsequence of the first n-1 numbers, and then judge with the nth number. To find the longest ascending subsequence of the first n-1 numbers, you can find the longest ascending subsequence of the first n-2 numbers...until you find the longest ascending subsequence of the first 1 number, at which time LIS is of course 1 .

  Let's take an example: find the longest ascending subsequence of 2 7 1 5 6 4 3 8 9 . We define d(i) (i∈[1,n]) to denote the length of the longest ascending subsequence whose first i number ends with A[i].

  The first 1 number d(1)=1 subsequence is 2;

  The first 2 numbers 7 are preceded by 2 less than 7 d(2)=d(1)+1=2 The subsequence is 2 7

  The first 3 numbers are not smaller than 1 before 1, and 1 itself forms a subsequence of length 1 d(3)=1 The subsequence is 1

  The first 4 numbers 5 are preceded by 2 less than 5 d(4)=d(1)+1=2 The subsequence is 2 5

  The first 5 numbers 6 are preceded by 2 5 less than 6 d(5)=d(4)+1=3 The subsequence is 2 5 6

  The first 6 numbers 4 are preceded by 2 less than 4 d(6)=d(1)+1=2 The subsequence is 2 4

  The first 7 numbers 3 are preceded by 2 less than 3 d(3)=d(1)+1=2 The subsequence is 2 3

  The first 8 numbers 8 are preceded by 2 5 6 less than 8 d(8)=d(5)+1=4 The subsequence is 2 5 6 8

  The first 9 numbers 9 are preceded by 2 5 6 8 less than 9 d(9)=d(8)+1=5 The subsequence is 2 5 6 8 9

  d(i)=max{d(1),d(2),...,d(i)} We can see that the LIS of these 9 numbers is d(9)=5

  To sum up, d(i) is to find the longest ascending subsequence that ends with A[i], before A[i] +1, when there is no smaller number than A[i] before A[i], d(i)=1. The largest of all d(i) is the longest ascending subsequence.

 

#include <cstdio> 
#include <cstring>
const int MAXN = 100100;
const int INF = 0x3f3f3f3f;
int a[MAXN];
int d[MAXN];

int find(int l, int r, int key)
{
    if (l == r)return l;
    int mid = (l + r) >> 1;
    if (key>d[mid])return find(mid + 1, r, key);
    else return find(1, mid, key);
}

intmain ()
{
    int n;
    while (scanf("%d", &n) != EOF)
    {
        memset(d, 0, sizeof(d));
        for (int i = 0; i<n; i++)scanf("%d", &a[i]);
        int len = 0;
        d[0] = -INF;
        for (int i = 0; i<n; i++)
        {
            if (a[i]>d[len])d[++len] = a[i];
            else
            {
                int j = find( 1 , len, a[i]);              // find the position of a[i] in d array 
                d[j] = a[i];                             // then replace it 
            }
        }
        printf("%d\n", len);
    }
    return 0;
}

 

2018-04-29

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325031893&siteId=291194637