zoukankan      html  css  js  c++  java
  • Dynamic Programming(动态规划)

    Question:

    给定一个最大为10,000的整型序列(每个值的大小在0到100,000)之间,求最大递减子序列。子序列可以不连续。

    Answer1:

    递归查找。递归查找从每个位置为开始的最长的递减子序列。

    效率低!

    Answer2:

    当从前向后难找到节约方法时,从后向前的方法此时通常会富有成效。

    这里就可以从序列的最后开始向前……

    (1)检查从当前位置到最后所有节点的bestsofar值。

    This is fairly clearly an O(N 2) algorithm. Check out its code:

    1  #include <stdio.h>
    2  #define MAXN 10000
    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)跟上一个算法比,这个为了缩短检查时间,定义了bestrun[MAXN],其长度就是最长子序列长度,其值就是第一次存入的值(随后变为“最好的”值)

    (原文: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//使用200000会堆栈溢出,而且题目要求也是20000,因此应改为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)使用二分查找改进速度,使时间复杂度变为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-sequence
    
    int
    main (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;
    }
  • 相关阅读:
    Windows Server 2012 64bit RMAN异机不完全恢复(迁移)
    dbms_jobs vs. dbms_scheduler_jobs
    Migrating from dbms_job to dbms_scheduler
    ORA-12537: TNS:connection closed
    win7 ins 30131 oracle 12c
    Vector源码分析
    LinkedList源码分析
    ArrayList源码分析
    jsp 显示日期
    Spring data redis 使用 pipelined 批量操作
  • 原文地址:https://www.cnblogs.com/growup/p/2029793.html
Copyright © 2011-2022 走看看