Question:
Calculate the maximum decreasing subsequence for an integer sequence with a maximum value of 10,000 (the size of each value ranges from 0 to 100,000. Subsequences can be discontinuous.
Answer1:
Recursive search. Recursively finds the longest descending subsequence starting from each position.
Low Efficiency!
Answer2:
When it is difficult to find a method to save from the past to the back, the method from the back to the front is usually fruitful.
Here we can start from the end of the sequence ......
(1) Check the bestsofar value of all nodes from the current position to the last.
This is fairly clearly an O (N2) algorithm. Check out its code:
1 # include <stdio. h>
2 # define maxn10000
3 main (){
4 long num [maxn], bestsofar [maxn];
5 file * In, * out;
6 long N, I, j, longest = 0;
7 In = fopen ("input.txt", "R ");
8 out = fopen ("output.txt", "W ");
9 fscanf (in, "% lD", & N );
10 For (I = 0; I <n; I ++) fscanf (in, "% lD", & num [I]);
11 bestsofar [n-1] = 1;
12 For (I = n-1-1; I> = 0; I --){
13 bestsofar [I] = 1;
14 For (j = I + 1; j <n; j ++ ){
15 if (Num [J] <num [I] & bestsofar [J]> = bestsofar [I]) {
16 bestsofar [I] = bestsofar [J] + 1;
17 if (bestsofar [I]> longest) longest = bestsofar [I];
18}
19}
20}
21 fprintf (Out, "bestsofar is % d \ n", longest );
22 exit (0 );
23}
(2) Keep up with an algorithm. To shorten the check time, bestrun [maxn] is defined. Its length is the longest part of the sequence, the value is the value saved for the first time (and then changed to the "best" value)
(Original article: Implement an array 'bestrun 'whose index is the length of a long subsequence and whose value is the first (and, as it turns out, 'best ') integer that heads that subsequence .)
Here's a coding of this algorithm:
1 # include <stdio. h>
2 # define maxn 200000 // stack overflow occurs when 200000 is used, and the question requirement is 20000. Therefore, it should be changed to 20000.
3 main (){
4 file * In, * out;
5 long num [maxn], bestrun [maxn];
6 long N, I, j, highestrun = 0;
7 In = fopen ("input.txt", "R ");
8 out = fopen ("output.txt", "W ");
9 fscanf (in, "% lD", & N );
10 For (I = 0; I <n; I ++) fscanf (in, "% lD", & num [I]);
11 bestrun [0] = num [n-1];
12 highestrun = 1;
13 For (I = n-1-1; I> = 0; I --){
14 if (Num [I] <bestrun [0]) {
15 bestrun [0] = num [I];
16 continue;
17}
18 For (j = highestrun-1; j> = 0; j --){
19 if (Num [I]> bestrun [J]) {
20 if (j = highestrun-1 | num [I] <bestrun [J + 1]) {
21 bestrun [++ J] = num [I];
22 if (j = highestrun) highestrun ++;
23 break;
24}
25}
26}
27}
28 printf ("Best is % d \ n", highestrun );
29 exit (0 );
30}
(3) Use binary search to improve the speed and change the time complexity to O (nlgn)
#include <stdio.h>#define SIZE 200000#define MAX(x,y) ((x)>(y)?(x):(y))int best[SIZE]; // best[] holds values of the optimal sub-sequenceintmain (void) { FILE *in = fopen ("input.txt", "r"); int i, n, k, x, sol; int low, high; fscanf (in, "%d", &n);// N = how many integers to read in // read in the first integer fscanf (in, "%d", &best[0]); sol = 1; for (i = 1; i < n; i++) { best[i] = -1; fscanf (in, "%d", &x); if(x >= best[0]) { k = 0; best[0] = x; } else { // use binary search instead low = 0; high = sol-1; for(;;) { k = (int) (low + high) / 2; // go lower in the array if(x > best[k] && x > best[k-1]) { high = k - 1; continue; } // go higher in the array if(x < best[k] && x < best[k+1]) { low = k + 1; continue; } // check if right spot if(x > best[k] && x < best[k-1]) best[k] = x; if(x < best[k] && x > best[k+1]) best[++k] = x; break; } } sol = MAX (sol, k + 1); } printf ("best is %d\n", sol); fclose(in); return 0;}