当前位置:   article > 正文

最大连续子数组的暴力\分治\DP方法_最大连续子数组分治

最大连续子数组分治

最大连续子数组:给定一组有正有负的数组,从中找出和最大的连续子数组。

一 暴力求解

设置两个for循环,分别求从1\2\3……个元素为起始元素的最大子数组和。过程中不断使用if条件判断更新maxsum的值。时间复杂度O(n2)。

代码如下:

  1. #include <bits/stdc++.h> //万能头文件
  2. using namespace std;
  3. int main()
  4. {
  5. int n;//数组长度
  6. while(cin>>n)
  7. {
  8. int a[n+5];
  9. for(int i=0;i<n;i++)
  10. {
  11. cin>>a[i];
  12. }
  13. int MaxSum,ThisSum;
  14. MaxSum=0;
  15. for(int i=0;i<n;i++)
  16. {
  17. ThisSum=0;
  18. for(int j=i;j<n;j++)
  19. {
  20. ThisSum+=a[j];
  21. if(ThisSum>MaxSum) MaxSum=ThisSum;
  22. }
  23. }
  24. cout<<MaxSum<<endl;
  25. }
  26. }
二 分治求解

步骤: 
1. 将序列分为左右两个子数组 
2. 递归地求两个子数组的最大和 
3. 从中间的点分别找出左右,跨过分界线的最大子数组的和 
4. 

代码如下:

  1. #include <iostream>
  2. using namespace std;
  3. int MAX3(int A,int B,int C)
  4. {
  5. return A>B?A>C?A:C:B>C?B:C;
  6. }
  7. int DivideandConquer(int a[],int left,int right)
  8. {
  9. int MaxleftSum,MaxrightSum;//左右两子数组中的最大子数组和
  10. int MaxleftborderSum,MaxrightborderSum;//经过中点的左右子数组最大和
  11. int LeftborderSum,RightborderSum;//过程量
  12. int center,i;
  13. if(left == right) //递归终止条件,子数组只有一个数字
  14. return a[left];
  15. center=(left+right)/2;
  16. MaxleftSum=DivideandConquer(a,left,center);
  17. MaxrightSum=DivideandConquer(a,center+1,right);
  18. //跨界求最大子数组和
  19. MaxleftborderSum = 0; LeftborderSum = 0;
  20. for (i = center; i >= left; i--)
  21. {
  22. LeftborderSum += a[i];
  23. if(LeftborderSum > MaxleftborderSum)
  24. MaxleftborderSum = LeftborderSum;
  25. }//左边扫描结束
  26. MaxrightborderSum = 0; RightborderSum = 0;
  27. for (i = center+1; i < right; i++)
  28. {
  29. RightborderSum += a[i];
  30. if(RightborderSum > MaxrightborderSum)
  31. MaxrightborderSum = RightborderSum;
  32. }//右边扫描结束
  33. return MAX3(MaxleftSum,MaxrightSum,MaxleftborderSum+MaxrightborderSum);
  34. }
  35. int MaxSubseq3(int a[],int n)
  36. {
  37. return DivideandConquer(a,0,n-1);
  38. }
  39. int main()
  40. {
  41. int n;
  42. while(cin>>n)
  43. {
  44. int a[n+5];
  45. for(int i=0;i<n;i++)
  46. {
  47. cin>>a[i];
  48. }
  49. cout<<MaxSubseq3(a,n);
  50. }
  51. }

3 DP法

使用一个for循环,只要sum的值小于0就丢弃,重新计数。

此法需保证数组元素有正有负。

因为有正有负,所以最大值一定大于0。

  1. int Maxsubseqdp(int a[],int n)
  2. {
  3. int ThisSum,MaxSum;
  4. MaxSum=0;
  5. ThisSum=0;
  6. for(int i=0;i<n;i++)
  7. {
  8. ThisSum+=a[i];
  9. if(ThisSum>MaxSum) MaxSum=ThisSum;
  10. else if(ThisSum<0) ThisSum=0;
  11. }
  12. return MaxSum;
  13. }



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

闽ICP备14008679号