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