首页 > 代码库 > LIS 最长上升序列

LIS 最长上升序列

  1. #include <iostream>
  2. #include <stdlib.h>
  3. using namespace std;
  4. #define MAX 10000
  5. int num[MAX], n;
  6. /***********************************************************************************************
  7. 经典的O(n^2)的动态规划算法,设num[i]表示序列中的第i个数,
  8. dp[i]表示从1到i这一段中以i结尾的最长上升子序列的长度,初始时设dp[i] = 1(i = 1, 2, ..., len(A))。
  9. 则有动态规划方程:dp[i] = max{1, dp[j] + 1} (j = 1, 2, ..., i - 1, 且num[j] < num[i])。
  10. ***********************************************************************************************/
  11. int dp[MAX]; //save length
  12. int DP()
  13. {
  14. int maxn = 0;
  15. for(int i=0; i<=n; i++)
  16. {
  17. dp[i] = 1;
  18. for(int j=0; j<i; j++)
  19. {
  20. if(num[i]> num[j] && dp[i] < dp[j] + 1)
  21. dp[i] = dp[j] + 1;
  22. }
  23. if(dp[i] > dp[maxn])
  24. maxn = i;
  25. }
  26. return maxn;
  27. }
  28. /********************************************************************************************
  29. 时间复杂度 nlog(n)
  30. 开一个栈,每次取栈顶元素top和读到的元素temp做比较,如果temp > top 则将temp入栈;
  31. 如果temp < top则二分查找栈中的比temp大的第1个数,并用temp替换它。 最长序列长度即为栈的大小top。
  32. 这也是很好理解的,对于x和y,如果x < y且Stack[y] < Stack[x],用Stack[x]替换Stack[y],
  33. 此时的最长序列长度没有改变但序列Q的‘‘潜力‘‘增大了。
  34. 举例:原序列为1,5,8,3,6,7
  35. 栈为1,5,8,此时读到3,用3替换5,得到1,3,8;
  36. 再读6,用6替换8,得到1,3,6;再读7,得到最终栈为1,3,6,7。最长递增子序列为长度4。
  37. **********************************************************************************************/
  38. int Greedy()
  39. {
  40. int stack[MAX];
  41. int top = 0;
  42. int tp;
  43. stack[top] = num[0]; /* 第一个元素可能为0 */
  44. for(int i = 1; i<n; i++)
  45. {
  46. int low = 0, high = top;
  47. int mid;
  48. while(low <= high) /* 二分检索栈中比temp大的第一个数 */
  49. {
  50. mid = (low + high)/2;
  51. if(stack[mid] > num[i])
  52. low = mid + 1;
  53. else high = mid - 1;
  54. }
  55. if(low == top + 1) top++;
  56. stack[low] = num[i];
  57. }
  58. return top + 1;
  59. /* 最长序列数就是栈的大小(top+1) 最长上升序列存在stack中*/
  60. }



来自为知笔记(Wiz)


附件列表

     

    LIS 最长上升序列