分治法之最大子数组问题

自己敲出来的,先把代码贴上来,晚上有时间再写总结

#include<stdio.h>
#define N 10
struct Max{
	int low;
	int high;
	int sum;

};
int a[N];
Max Findcrossing(int* a,int low,int middle,int high);
Max FindSub(int* a,int low,int high);
int main()
{
	Max m;
	int i;
	for(i=0;i<N;i++)
		scanf("%d",&a[i]);
	m=FindSub(a,0,9);
	printf("%d\n%d\n%d",m.sum,m.low,m.high);

	return 0;
}
Max FindSub(int* a,int low,int high)
{
	Max max_sub;
	Max max_left;
	Max max_right;
	Max max_cross;

	if(high==low)
	{
		max_sub.high=high;
		max_sub.low=low;
		max_sub.sum=a[low];
	}
	else
	{
		int middle=(low+high)/2;

		max_left=FindSub(a,low,middle);
		max_right=FindSub(a,middle+1,high);
		max_cross=Findcrossing(a,low,middle,high);
		if(max_left.sum>=max_right.sum&&max_left.sum>=max_cross.sum)
		{
			max_sub.high=max_left.high;
			max_sub.low=max_left.low;
			max_sub.sum=max_left.sum;
		}
		else if(max_right.sum>=max_left.sum&&max_right.sum>=max_cross.sum)
		{
			max_sub.high=max_right.high;
			max_sub.low=max_right.low;
			max_sub.sum=max_right.sum;
		}
		else
		{
			max_sub.high=max_cross.high;
			max_sub.low=max_cross.low;
			max_sub.sum=max_cross.sum;
		}

	}

	return max_sub;
}
Max Findcrossing(int* a,int low,int middle,int high)
{
	int i,j;
	Max max_cross;

	int left_i,sum_left=0,MAX_left=-10000;
	for(i=middle;i>=low;i--)
	{
		sum_left+=a[i];
		if(sum_left>MAX_left)
		{
			MAX_left=sum_left;
			left_i=i;
		}
	}
	int right_j,sum_right=0,MAX_right=-10000;
	for(j=middle+1;j<=high;j++)
	{
		sum_right+=a[j];
		if(sum_right>MAX_right)
		{
			MAX_right=sum_right;
			right_j=j;
		}

	}
	max_cross.sum=MAX_left+MAX_right;
	max_cross.low=left_i;
	max_cross.high=right_j;
	return max_cross;
}

  

时间: 2024-10-13 19:36:40

分治法之最大子数组问题的相关文章

分治法解决最大子数组问题

利用分治法解决最大子数组问题(对给定的数组得到该数组中具有最大和的子数组) /* * 对于给定的整数数组A,求出数组中具有最大和的子数组,最大和以及左右下标 * 思路:采用分治的方法,将数组分为两部分,则有最大和的子数组共有三种情况 * 在数组左边,在数组右边,跨越数组中点 */ #include <iostream> using namespace std; //存放左右边界值以及sum值的结构体 /*特别注意结构体的使用!!!!!!!!!!!*/ struct SumBorder { in

分治法求解最大子数组问题

/*     本问题是求解最大子数组问题     普通方法的复杂度为n^2     现在尝试给出一种小于n^2的算法     当然数组中必须要有负数,不然没有意义     本例中使用分治策略 */ #include<stdio.h> #include<stdlib.h> //定义返回结构体 typedef struct result {     int left; //左索引     int right; //右索引     int sum; //最大和 }*Res; //求解包含

算法题|-分治法解决最大子数组问题

分治法就是将一个复杂难解决问题拆成一些容易解决的小问题,再依次解决而最终解决整个问题 new int[] { 2, -3, 4, 67, 6 } 这样一个下标为0到4的数组,要找最大子数组,需要将其拆分成两个子数组,mid=(0+4)/2 即为0~mid的左数组和mid+1~4的右数组 最大子数组可能会出现在以下三个地方 左数组中的某个最大子数组 右数组中的某个最大子数组 以mid为界,向左找到一个最大数组,向右找到一个最大数组,将两个数组合并 第三种情况非常容易得到,通过遍历查找就可以解决,而

分治法计算最大字数组(Python)

比如你获得了一个投资某个股票的机会,并且,你已经准确知道了将来几天这一只股票的相对于前一天的插值,比如为[13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7],那么就有一个问题,从那一天买入,哪一天卖出获益最大?这里就是一个最大字数组问题. 最大字数组问题:在一个数组中找出最大的非空连续子数组 常见方法,暴力求解找出所有的组合,共有C(n,2)种选择,时间复杂度Theta(n^2) 分治法求解最大字数组问题,计算复杂度theta(nlogn) 分

sicily 1136(线段树+最大子数组)

题目链接:sicily 1136 解题思路: 要求区间内的最大子数组,而且访问可能很频繁,时间复杂度需要达到o(n*logn),于是就很自然地想到了线段树.我们可以用线段树来保存区间的最大子数组,但是仔细想想又不对劲了,如果访问的区间跨越了两个小区间怎么破,所以,这并不只是一个简单的求区间连续和的问题,还要有点小技巧. 最大子数组怎么得到的,还记得<算法导论>里面讲过一种用分治法来求最大子数组的方法吗(分治法之最大子数组)? 假设我们要求区间[low , high]的最大子数组,并且已知[lo

最大子数组求和并进行条件组合覆盖测试

简介 算法导论第四章介绍过使用分治法求最大子数组问题,其基本思想就是把一个数组分成三部分,a[0:n/2],a[n/2+1:n],a[j:k] (其中0<=j<=n/2,n/2+1<=k<=n),通过递归分别求出他们的最大子数组和,然后再从中挑出最大的一个值,即为该数组的最大子数组值,该算法的时间复杂度为O(nlogn) 白盒测试有语句覆盖.判定覆盖.条件覆盖.判定/条件覆盖.条件组合覆盖这五个覆盖标准 环境:Ubuntu 16.04 语言:C++ 测试工具:GTest(Gtest

编程之美4:那些常被考到的关于数组的最大子数组问题

楼主这篇文章的目的是要带大家梳理一下,有关于求子数组问题.如求子数组的最大和,求最大和的子数组,求最大积的子数组等一系列问题.今天阳光明媚,楼主今天心情很好哦,愿大家开心每一天,哈哈.Are you ready?开始了哦~~~ 题目一:求子数组的最大和 题目求子数组的最大和,这里需要注意的一个问题就是,子数组那么便意味着是连续的一段数据.我们可以先写的例子,方便我们注意到要考虑的一些问题. 数组:[1, -2, 3, 5, -3, 2] 应该返回8,最大和的子数组为3,5 数组:[0, -2,

结对编程之求首尾相连数组中最大子数组的和

1.题目: 返回一个整数数组中最大子数组的和. 2.要求: 输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大.同时返回最大子数组的位置.求所有子数组的和的最大值.要求时间复杂度为O(n). 3.设计思想: 分情况讨论最大子数组可能出现的情况,第一种为正常情况,没有超过数组范围,第二种则比较复杂,要用到环的一部分元素,分而求出两

分治法——最大子数组

题目描述: 给定一个n个元素的数组a,求a[i]+a[i+1]+-+a[j]的最大值(0 <= i <= j < n) 解题思路: 我们来试试用分治法来解决这个问题.首先我们想要找到一个子数组a[i-j]为最大子数组,我们假设数组的中点为mid,可以将数组a[low-high]分成两个子数组:a[low-mid]和a[mid+1-high],那么最大子数组必然为下述三种可能之一: 1) low <= i , j <= mid ; 2) mid < i , j <=