分治法求最大子段和

/*
1.分治算法
2.时间复杂度不超过O(nlogn) 
*/
#include<stdio.h>
#define N 50
int lefts,rights; 
int MAXSUM(int data[],int left,int right)
{
	int sum = 0;
	if(left == right)
	{
		sum = data[left]>0 ? data[left] : 0;
	}	
	else
	{
		int center = (left + right)/2;
		int leftsum = MAXSUM(data, left, center);
		int rightsum = MAXSUM(data, center+1, right);
		int S1 = 0,LEFT = 0;//LEFT从中间往两边走 
		for(int i = center; i >= left; i--)
		{
			LEFT += data[i];
			if(LEFT > S1)
			{
				S1 = LEFT;
				lefts = i;
			}
				
		}
		int S2 = 0,RIGHT = 0;
		for(int i = center+1; i <= right; i++)
		{
			RIGHT += data[i];
			if(RIGHT > S2)
			{
				S2 = RIGHT;
				rights = i;
			}
				
		}
		sum = S1 + S2;
		if(sum < leftsum)
		{
			sum = leftsum;
			lefts = left;
			rights = center;
		}
		if(sum < rightsum)
		{
			sum =rightsum;
			lefts = center+1;
			rights = right;
		}
			
	}
	return sum;	
}
int main()
{
	//输入数据 
	int n,data[N];
	printf("输入元素个数:\n"); 
	scanf("%d",&n);
	printf("输入数据:\n");
	for(int i = 0; i<n; i++)
	{
		scanf("%d",&data[i]);
	}
	int left=0,right=n-1; 
	//求最大字段和函数 
	int sum=MAXSUM(data,left,right);
	printf("最大子段和为:%d\n",sum);
	printf("开始下标为%d,结束下标为%d",lefts,rights);
 }
//-2 11 -4 13 -5 -2

主要算法:

        一分为二,先分别计算左边和右边的最大子段和,然后从中间往两边扩展计算最大字段和。左边、右边、从中间往两边取最大者为最大字段和!

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
分治法最大子段和的思路是将问题分成两个子问题,分别出左半边和右半边的最大子段和,然后再出跨越中间的最大子段和。最终的最大子段和就是这三个中的最大值。 最大字段序列可以通过记录最大子段和的起始位置和结束位置来得到。具体实现可以参考以下代码: ``` def max_subarray(nums, left, right): if left == right: return nums[left], left, right mid = (left + right) // 2 left_sum, left_start, left_end = max_subarray(nums, left, mid) right_sum, right_start, right_end = max_subarray(nums, mid+1, right) cross_sum, cross_start, cross_end = max_cross_subarray(nums, left, mid, right) if left_sum >= right_sum and left_sum >= cross_sum: return left_sum, left_start, left_end elif right_sum >= left_sum and right_sum >= cross_sum: return right_sum, right_start, right_end else: return cross_sum, cross_start, cross_end def max_cross_subarray(nums, left, mid, right): left_sum = float('-inf') sum = 0 for i in range(mid, left-1, -1): sum += nums[i] if sum > left_sum: left_sum = sum max_left = i right_sum = float('-inf') sum = 0 for i in range(mid+1, right+1): sum += nums[i] if sum > right_sum: right_sum = sum max_right = i return left_sum + right_sum, max_left, max_right ``` 其中,`max_subarray`函数用于最大子段和,`max_cross_subarray`函数用于跨越中间的最大子段和。两个函数都是递归实现的。最终的最大子段和和最大字段序列可以通过`max_subarray`函数返回的三个值得到。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

try again!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值