当前位置:   article > 正文

算法设计与分析--求最大子段和问题(蛮力法、分治法、动态规划法) C++实现

规划算法 c++

算法设计与分析--求最大子段和问题

问题描述:

给定由n个整数组成的序列(a1,a2, …,an),求该序列形如

的子段和的最大值,当所有整数均为负整数时,其最大子段和为0。


利用蛮力法求解:

  1. int maxSum(int a[],int n)
  2. {
  3. int maxSum = 0;
  4. int sum = 0;
  5. for(int i = 0; i < n; i++) //从第一个数开始算起
  6. {
  7. for(int j = i + 1; j < n; j++)//从i的第二个数开始算起
  8. {
  9. sum = a[i];
  10. a[i] += a[j];
  11. if(a[i] > sum)
  12. {
  13. sum = a[i]; //每一趟的最大值
  14. }
  15. }
  16. if(sum > maxSum)
  17. {
  18. maxSum = sum;
  19. }
  20. }
  21. return maxSum;
  22. }


利用分治法求解:

  1. int maxSum(int a[],int left, int right)
  2. {
  3. int sum = 0;
  4. if(left == right) //如果序列长度为1,直接求解
  5. {
  6. if(a[left] > 0) sum = a[left];
  7. else sum = 0;
  8. }
  9. else
  10. {
  11. int center = (left + right) / 2; //划分
  12. int leftsum = maxSum(a,left,center); //对应情况1,递归求解
  13. int rightsum = maxSum(a, center + 1, right);//对应情况2, 递归求解
  14. int s1 = 0;
  15. int lefts = 0;
  16. for(int i = center; i >= left; i--) //求解s1
  17. {
  18. lefts += a[i];
  19. if(lefts > s1) s1 = lefts; //左边最大值放在s1
  20. }
  21. int s2 = 0;
  22. int rights = 0;
  23. for(int j = center + 1; j <= right; j++)//求解s2
  24. {
  25. rights += a[j];
  26. if(rights > s2) s2 =rights;
  27. }
  28. sum = s1 + s2; //计算第3钟情况的最大子段和
  29. if(sum < leftsum) sum = leftsum; //合并,在sum、leftsum、rightsum中取最大值
  30. if(sum < rightsum) sum = rightsum;
  31. }
  32. return sum;
  33. }


利用动态规划法求解:

  1. int DY_Sum(int a[],int n)
  2. {
  3. int sum = 0;
  4. int *b = (int *) malloc(n * sizeof(int)); //动态为数组分配空间
  5. b[0] = a[0];
  6. for(int i = 1; i < n; i++)
  7. {
  8. if(b[i-1] > 0)
  9. b[i] = b[i - 1] + a[i];
  10. else
  11. b[i] = a[i];
  12. }
  13. for(int j = 0; j < n; j++)
  14. {
  15. if(b[j] > sum)
  16. sum = b[j];
  17. }
  18. delete []b; //释放内存
  19. return sum;
  20. }





完整测试程序:

  1. #include<iostream>
  2. #include<time.h>
  3. #include<Windows.h>
  4. using namespace std;
  5. #define MAX 10000
  6. int BF_Sum(int a[],int n)
  7. {
  8. int max=0;
  9. int sum=0;
  10. int i,j;
  11. for (i=0;i<n-1;i++)
  12. {
  13. sum=a[i];
  14. for(j=i+1;j<n;j++)
  15. {
  16. if(sum>=max)
  17. {
  18. max=sum;
  19. }
  20. sum+=a[j];
  21. }
  22. }
  23. return max;
  24. }
  25. int maxSum1(int a[],int left, int right)
  26. {
  27. int sum = 0;
  28. if(left == right) //如果序列长度为1,直接求解
  29. {
  30. if(a[left] > 0) sum = a[left];
  31. else sum = 0;
  32. }
  33. else
  34. {
  35. int center = (left + right) / 2; //划分
  36. int leftsum = maxSum1(a,left,center); //对应情况1,递归求解
  37. int rightsum = maxSum1(a, center + 1, right);//对应情况2, 递归求解
  38. int s1 = 0;
  39. int lefts = 0;
  40. for(int i = center; i >= left; i--) //求解s1
  41. {
  42. lefts += a[i];
  43. if(lefts > s1) s1 = lefts; //左边最大值放在s1
  44. }
  45. int s2 = 0;
  46. int rights = 0;
  47. for(int j = center + 1; j <= right; j++)//求解s2
  48. {
  49. rights += a[j];
  50. if(rights > s2) s2 =rights;
  51. }
  52. sum = s1 + s2; //计算第3钟情况的最大子段和
  53. if(sum < leftsum) sum = leftsum; //合并,在sum、leftsum、rightsum中取最大值
  54. if(sum < rightsum) sum = rightsum;
  55. }
  56. return sum;
  57. }
  58. int DY_Sum(int a[],int n)
  59. {
  60. int sum = 0;
  61. int *b = (int *) malloc(n * sizeof(int)); //动态为数组分配空间
  62. b[0] = a[0];
  63. for(int i = 1; i < n; i++)
  64. {
  65. if(b[i-1] > 0)
  66. b[i] = b[i - 1] + a[i];
  67. else
  68. b[i] = a[i];
  69. }
  70. for(int j = 0; j < n; j++)
  71. {
  72. if(b[j] > sum)
  73. sum = b[j];
  74. }
  75. delete []b; //释放内存
  76. return sum;
  77. }
  78. int main()
  79. {
  80. int num[MAX];
  81. int i;
  82. const int n = 40;
  83. LARGE_INTEGER begin,end,frequency;
  84. QueryPerformanceFrequency(&frequency);
  85. //生成随机序列
  86. cout<<"生成随机序列:";
  87. srand(time(0));
  88. for(int i = 0; i < n; i++)
  89. {
  90. if(rand() % 2 == 0)
  91. num[i] = rand();
  92. else
  93. num[i] = (-1) * rand();
  94. if(n < 100)
  95. cout<<num[i]<<" ";
  96. }
  97. cout<<endl;
  98. //蛮力法//
  99. cout<<"\n蛮力法:"<<endl;
  100. cout<"最大字段和:";
  101. QueryPerformanceCounter(&begin);
  102. cout<<BF_Sum(num,n)<<endl;
  103. QueryPerformanceCounter(&end);
  104. cout<<"时间:"
  105. <<(double)(end.QuadPart - begin.QuadPart) / frequency.QuadPart
  106. <<"s"<<endl;
  107. cout<<"\n分治法:"<<endl;
  108. cout<"最大字段和:";
  109. QueryPerformanceCounter(&begin);
  110. cout<<maxSum1(num,0,n)<<endl;
  111. QueryPerformanceCounter(&end);
  112. cout<<"时间:"
  113. <<(double)(end.QuadPart - begin.QuadPart) / frequency.QuadPart
  114. <<"s"<<endl;
  115. cout<<"\n动态规划法:"<<endl;
  116. cout<"最大字段和:";
  117. QueryPerformanceCounter(&begin);
  118. cout<<DY_Sum(num,n)<<endl;
  119. QueryPerformanceCounter(&end);
  120. cout<<"时间:"
  121. <<(double)(end.QuadPart - begin.QuadPart) / frequency.QuadPart
  122. <<"s"<<endl;
  123. system("pause");
  124. return 0;
  125. }

测试结果:



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

闽ICP备14008679号