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 Y , 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)