The maximum length sequence nlogn && decreased output sequence

Not achieve the longest decline sequence:

       Sequence using monotonicity .

  For any monotonic sequence, such as a  . 1 2 . 3 . 4 . 5     (a single added), if the time to add a number to the end of the sequence  X , we only care and x Size 5, if  the X- > 5 , increase success, otherwise fail. Because relatively normal code from scratch, and and x 1,2,3,4 size comparison is useless, this operation will only lead to a waste of time, so the efficiency is very low. Monotonic sequence, only the last record number of each sequence, each adding a number  x , a direct comparison of  x  size and the number of the end. Only the last number is useful, it represents the maximum value of the sequence.

  To achieve this is to open a new array d, use it to record the last element of each sequence, in order not to decrease the maximum, for example,D [k] represents the length of the last element is not reduced to the minimum sequence of k.

  We  L E n-  represents the longest sequence length Couchu current, i.e. the current  d  in that the final position.

  Thus it is  E A S , and each read a number  x , if  x  is greater than equal to  D [ L E n- ] , directly to  D [ L E n- + . 1 ] = x , then  L E n- + + , equivalent to x received behind the longest sequence;

  If  x  is less than d [len], described x can not receive back the longest sequence, then look for d number of end [1 ... len-1] are less than or equal Of the sequence x, then x back to it. For example, if the current  X == . 7 , L E n- == . 8 :

1

2

3

4

5

6

7

8

2

3

4

7

7

10

12

29

  D [ . 1 ] D [ . 5 ]  is less than equal to  X , if the  D [ . 1 ]  , after a x, the  D [ 2 ]  should be replaced x, but the  D [ 2 ] == . 3 , than x is small, the number able to take more, with  7  enchant 3 is clearly not cost-effective, so x can not be connected d [1] after. Similarly,d [2] ⋯ d [4] can not be connectedx. Since  D [ . 5 ] X  and  X < D [ . 6 ] ,7 can be compared More then 10 numbers, the selected  D [ . 5 ]  followed by x, with Replace x 10。

  According to this operation, easy to know the array d must be monotonic sequences, can be used to find the time-half! Dichotomy efficiency logn, so the efficiency of the algorithm is to nlogn friends ~

The output sequence to achieve:

       Like a long time, I think nlogn approach is also possible output sequence, this time need to add a c array is used to record the location of each element in the longest sequence, i.e., c [i] represents a [i] is placed in the first position of the sequence number.

  Output, starting from the end of the array a, and c is in reverse order to identify len, len-2 ... 3, elements len-1, 2, 1, and then looking to find a c [i] -1, until it finds c [i] is the number 1.

  for example:

a: 13 7 9 16 38 24 37 18 44 19 21 22 63 15
c: 1 1 2 3 4 4 5 4 6 5 6 7 8 3

  len = 8;

  We start from the 15 elements 8 c is looking backwards to find 63, then find c 7 to find 22 c to find 6 of 21 find, find c ...... 5 and so on.

  Thus, we arrive at the sequence 63,22,21,19,18,16,9,7

  Reverse output, it is a 7,9,16,18,19,21,22,63

  Why this method is it? Reverse lookup to ensure that the two conditions:

    - If there are a plurality of the same c number, it must be updated later date;

    - a condition in ensuring the premise of looking for reverse, the latter will be able to count the number of front to the back.

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stack>
 6 #define int long long
 7 #define maxn 1000+10
 8 using namespace std;
 9 inline int read() 
10 {
11     int x=0;
12     bool f=1;
13     char c=getchar();
14     for(; !isdigit(c); c=getchar()) if(c=='-') f=0;
15     for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0';
16     if(f) return x;
17     return 0-x;
18 }
19 inline void write(int x)
20 {
21     if(x<0){putchar('-');x=-x;}
22     if(x>9)write(x/10);
23     putchar(x%10+'0');
24 }
25 int n,len;
26 int a[maxn],last[maxn],site[maxn];
27 stack<int> s;
28 signed main()
29 {
30     n=read();
31     for(int i=1;i<=n;i++) a[i]=read();
32     if(n==0) 
33     {
34         write(0);
35         return 0;
36     }
37     len=1;
38     last[1]=a[1];
39     site[1]=1;
40     for(int i=2;i<=n;i++)
41     {
42         if(a[i]>=last[len]) 
43         {
44             last[++len]=a[i];
45             site[i]=len;
46         }
47         else 
48         {
49             int now=lower_bound(last+1,last+len+1,a[i])-last;
50             last[now]=a[i];
51             site[i]=now;
52         }
53     }
54     printf("max=");
55     write(len);
56     printf("\n");
57     for(int i=n,j=len;i>=1;i--)
58     {
59         if(site[i]==j) 
60         {
61             s.push(a[i]);
62             j--;
63         }
64         if(j==0) break;
65     }
66     while(!s.empty())
67     {
68         int put=s.top();
69         s.pop();
70         write(put);
71         printf(" ");
72     }
73     return 0;
74 }

Please Gangster treatise(Anyway, I do not know what that means treatise)

Guess you like

Origin www.cnblogs.com/handsome-zyc/p/11609456.html