利用分而治之求最大子列和

简介: 利用分而治之求最大子列和

一、什么是分而治之?

           

分而治之方法与软件设计的模块化方法非常相似。为了解决一个大的问题,可以:

  • 1) 把它分成两个或多个更小的问题;
  • 2) 分别解决每个小问题;3) 把各小问题的解答组合起来,即可得到原问题的解答。

小问题通常与原问题相似,可以递归地使用分而治之策略来解决。

二、求最大子列和

对于这个问题,我们首先将数组分解:

然后求出每个序列的最大和,但是在合并的时候有三种情况:

  • 最大序列和出现在左序列
  • 最大序列和出现在右序列
  • 最大序列和由左右序列的部分组成

对于这三种情况,进行比较,取最大

代码实现 :

#include<stdio.h>
#include<limits.h>
#include<math.h>
int max(int a, int b)
{
  return a > b ? a : b;
}
int maxsubArray(int num[], int low, int high)
{
  if (low == high)
  {//分解到只有一个元素的情况
    if (num[low] > INT_MIN)
    {
      return num[low];
    }
    else
    {
      return INT_MIN;
    }
  }
  int mid = (low + high) / 2;//从中间元素开始分解
  int maxLeft=maxsubArray(num, low, mid);//求左边的最大子序列和
  int maxRight=maxsubArray(num, mid + 1, high);//求右边的最大子序列和
  //最大序列和由左右序列的部分组成
  int sumLeft = INT_MIN;
  int sumRight = INT_MIN;
  int a = 0, b = 0;
  for (int i =mid; i>=low; i--)
  {
    a += num[i];
    if (a > sumLeft)
    {
      sumLeft = a;
    }
  }
  for (int j = mid + 1; j <= high; j++)
  {
    b += num[j];
    if (b > sumRight)
    {
      sumRight = b;
    }
  }
  int sum = sumLeft + sumRight;
  return max(max(maxLeft, maxRight), sum);
 
}
int main()
{
  int num[12] = { 1,-2,4,5,-2,8,3,-2,6,3,7,-1 };
  printf("%d\n",maxsubArray( num,0, 11));
  return 0;
}

运行结果:


目录
相关文章
|
6月前
|
机器学习/深度学习 算法 测试技术
【动态规划】C++算法:446等差数列划分 II - 子序列
【动态规划】C++算法:446等差数列划分 II - 子序列
|
6月前
|
算法 NoSQL 容器
|
算法
【学会动态规划】等差数列划分(22)
【学会动态规划】等差数列划分(22)
53 0
|
存储 算法
【回溯算法篇】组合问题(上)
【回溯算法篇】组合问题(上)
【回溯算法篇】组合问题(上)
|
算法 搜索推荐
分治算法的理解与应用
分治算法的理解与应用
125 0
【回溯算法篇】组合问题(下)
【回溯算法篇】组合问题(下)
【回溯算法篇】组合问题(下)
|
算法 搜索推荐 Go
分治算法其实很有趣(下)
分治法可能是最著名的通用算法设计技术了。虽然它的名气可能和它那好记的名字有关,但它的确是当之无愧:因为很多有效的算法实际上就是这个通用算法的特殊实现。
 分治算法其实很有趣(下)
分治算法其实很有趣(上)
分治法可能是最著名的通用算法设计技术了。虽然它的名气可能和它那好记的名字有关,但它的确是当之无愧:因为很多有效的算法实际上就是这个通用算法的特殊实现。
分治算法其实很有趣(上)
|
算法
分治算法——棋盘覆盖
分治算法——棋盘覆盖
166 0