Red Huang

Red Huang

最长递增子序列:动态规划

计算 LIS 的长度

  1. int s [5]; // 用来存 sequence

  2. int array [5]; // 第 x 格的值为 sequence: s [0]~s [x] 的 LIS 长度

  3. int LIS()

  4. {

  5. // 初始化,每一个数字本身就是长度为一的subsequence
    
  6. for (int i=0; i<5; i++) array\[i\] = 1;
    
  7. // LIS
    
  8. for (int i=0; i<5; i++)
    
  9.     for (int j=i+1; j<5; j++)   // 找出能接在s\[i\]后面的数字
    
  10.         if (s\[j\] > s\[i\])        // 若是可以接,长度就增加
    
  11.             array\[j\] = max(array\[j\], array\[i\] + 1);
    
  12. // array中最大的值即为LIS的长度
    
  13. int ans = 0;
    
  14. for (int i=0; i<5; i++)
    
  15.     ans = max(ans, array\[i\]);
    
  16. return ans;
    
  17. }

找出一个 LIS

  1. int s[5];

  2. int array[5];

  3. int prev [5]; //prev [x] 纪录 s [x] 是接在哪个位置的数字后面

  4.              // 如果它前面没有数字就纪录-1
    
  5. int LIS()

  6. {

  7. for (int i=0; i<5; i++) array\[i\] = 1;
    
  8. // -1 代表这个数字没有接在其他数字之后
    
  9. for (int i=0; i<5; i++) prev\[i\] = -1;
    
  10. for (int i=0; i<5; i++)
    
  11.     for (int j=i+1; j<5; j++)
    
  12.         if (s\[j\] > s\[i\])
    
  13.             if (array\[i\] + 1 > array\[j\])
    
  14.             {
    
  15.                 array\[j\] = array\[i\] + 1;
    
  16.                 prev\[j\] = i;   // s\[j\] 接在 s\[i\] 后面
    
  17.             }
    
  18. int ans = 0, pos = 0;
    
  19. for (int i=0; i<5; i++)
    
  20.     if (ans > array\[i\])
    
  21.     {
    
  22.         ans = array\[i\];
    
  23.         pos = i;
    
  24.     }
    
  25. print\_LIS(pos); // 印出一个LIS
    
  26. return ans;
    
  27. }

  28. // 递归版

  29. void print_LIS(int x)

  30. {

  31. if (prev\[x\] != -1) print\_LIS(prev\[x\]);
    
  32. cout << seq\[x\] << " ";
    
  33. }

  34. // 迴圈版,但是顺序是颠倒的。

  35. void print_LIS(int x)

  36. {

  37. for (; prev\[x\] != -1; x = prev\[x\])
    
  38.     cout << seq\[x\] << " ";
    
  39. }

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。