当前位置:   article > 正文

动态规划之最长单调递增子序列

题目4:采用动态规划策略设计实现算法,找出由n个数组成的序列的最长单调递增子序列

问题描述:
找出由n个数组成的序列的最长单调递增子序列

解法一:

原序列记为X,对n个数递增排序,构造一个新序列Y, 对X,Y求其最长公共子序列即可.

  1. /*
  2. * description: 最长单调递增子序列
  3. * 问题描述:
  4. * 找出由n个数组成的序列的最长单调递增子序列
  5. * 算法设计:
  6. * 解法一:
  7. * 原序列记为X,对n个数递增排序,构造一个新序列Y, 对X,Y求其最长公共子序列即可.
  8. *
  9. * auther:cm
  10. * date:2010/11/17
  11. */
  12. import java.util.LinkedList;
  13. import java.util.List;
  14. public class LISLength
  15. {
  16. private int[] arrX;
  17. private int[] arrY;
  18. private int[][] c;
  19. public LISLength(int[] arr)
  20. {
  21. arrX = new int[arr.length + 1];
  22. arrY = new int[arr.length + 1];
  23. System.arraycopy(arr,0,arrX,1,arr.length);
  24. System.arraycopy(arr,0,arrY,1,arr.length);
  25. selectSort(arrY, arrY.length - 1);
  26. lisLength();
  27. }
  28. //计算最长公共子序列
  29. public void lisLength()
  30. {
  31. c = new int[arrX.length][arrY.length];
  32. for (int i = 1; i < arrX.length; i++)
  33. {
  34. for (int j = 1; j < arrY.length; j++)
  35. {
  36. if (arrX[i] == arrY[j])
  37. {
  38. c[i][j] = c[i-1][j-1] + 1;
  39. }
  40. else
  41. {
  42. c[i][j] = max(c[i-1][j], c[i][j-1]);
  43. }
  44. }
  45. }
  46. }
  47. //返回最长单调递增子序列
  48. public List<Integer> getLIS()
  49. {
  50. LinkedList<Integer> list = new LinkedList<Integer>();
  51. int i = arrX.length - 1;
  52. int j = arrY.length - 1;
  53. while (i >= 1 && j >= 1)
  54. {
  55. if (arrX[i] == arrY[j])
  56. {
  57. list.addFirst(Integer.valueOf(arrX[i]));
  58. i--;
  59. j--;
  60. }
  61. else
  62. {
  63. if (c[i-1][j] > c[i][j-1])
  64. {
  65. i--;
  66. }
  67. else
  68. {
  69. j--;
  70. }
  71. }
  72. }
  73. return list;
  74. }
  75. private int max(int m, int n)
  76. {
  77. return m > n ? m : n;
  78. }
  79. //选择排序,0号空间不用
  80. private void selectSort(int[] a, int n)
  81. {
  82. for (int i = 1; i < n; i++)
  83. {
  84. int k = i;
  85. for (int j = i + 1; j <= n; j++)
  86. {
  87. if (a[k] > a[j])
  88. {
  89. k = j;
  90. }
  91. }
  92. if (k != i)
  93. {
  94. int temp = a[k];
  95. a[k] = a[i];
  96. a[i] = temp;
  97. }
  98. }
  99. }
  100. public static void main(String[] args)
  101. {
  102. int[] arr = {4, 2, 3, 1, 8};
  103. //int[] arr = {8,9,10,2,3,4,5,6};
  104. LISLength lis = new LISLength(arr);
  105. List<Integer> a = lis.getLIS();
  106. for (Integer item: a)
  107. {
  108. System.out.print(item + " ");
  109. }
  110. }
  111. }

序列X={4, 2, 3, 1, 8}

执行结果:

2 3 8

 

解法二:
1)用一个数组b[n]记录以a[i]结尾的最长单调递增子序列的长度;
2)序列的a的最长单调子序列的长度为max{b[i],0=<i<n};
3)b[i] = max{b[k],a[k]<=a[i]&&0=<k<i} + 1 ,b[0] = 1;

  1. /*
  2. * description:最长单调递增子序列
  3. * 问题描述:
  4. * 找出由n个数组成的序列的最长单调递增子序列
  5. * 算法设计:
  6. * 解法二:
  7. * 1)用一个数组b[n]记录以a[i]结尾的最长单调递增子序列的长度;
  8. * 2)序列的a的最长单调子序列的长度为max{b[i],0=<i<n};
  9. * 3)b[i] = max{b[k],a[k]<=a[i]&&0=<k<i} + 1 ,b[0] = 1;
  10. *
  11. * auther:cm
  12. * date:2010/11/17
  13. */
  14. public class LIS
  15. {
  16. private int[] a;
  17. private int[] b;
  18. public LIS(int[] a)
  19. {
  20. this.a = a;
  21. b = new int[a.length];
  22. }
  23. public void lis()
  24. {
  25. b[0] = 1;
  26. for (int i = 0; i < a.length; i++)
  27. {
  28. int k = 0;
  29. for (int j = 0; j < i; j++)
  30. {
  31. if (a[j] <= a[i] && k < b[j])
  32. {
  33. k = b[j];
  34. }
  35. }
  36. b[i] = k + 1;
  37. }
  38. int k = max(b);
  39. //输出结果
  40. print(k);
  41. }
  42. //求数组中最大值下标
  43. private int max(int[] b)
  44. {
  45. int max = b[0];
  46. int k = 0;
  47. for (int i = 0; i < b.length; i++)
  48. {
  49. if (max < b[i])
  50. {
  51. max = b[i];
  52. k = i;
  53. }
  54. }
  55. return k;
  56. }
  57. //输出
  58. public void print(int k)
  59. {
  60. for (int i = k - 1; i >= 0; i--)
  61. {
  62. if (b[k] == b[i] + 1 && a[i] <= a[k])
  63. {
  64. print(i);
  65. break;
  66. }
  67. }
  68. System.out.print(a[k] + " ");
  69. }
  70. public static void main(String[] args)
  71. {
  72. int[] a = {4, 2, 3, 1, 8};
  73. LIS lis = new LIS(a);
  74. lis.lis();
  75. }
  76. }

序列X={4, 2, 3, 1, 8}

执行结果:

2 3 8

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/521419
推荐阅读
相关标签
  

闽ICP备14008679号