算法(一)管窥算法

1.1最大连续子数组

给定一个数组A[0,1,…,n-1],求A的连续子数组,使得该子数组的和最大。

例如:数组:1,-2,3,10,-4,7,2,-5

最大子数组:3,10,-4,7,2

1.1.1 暴力法

直接求解。时间复杂度o(n^3)。
(等我学会C++!)

#include <stdio.h>
#include <math.h>

int MaxSubArray(int a[],int n)
{
	int max=a[0];
	int crr;
	for(int i=0;i<n;i++)
	{
		for(int j=i;j<n;j++)
		{
			crr=0;
			for(int k=i;k<=j;k++)
			{
				crr+=a[k];
				
			}
			if(crr>max)
			   max=crr;
		}
	}
	return max;
}

int main()
{
	printf("请输入数组个数:\n");
	int n;
	scanf("%d",&n);
	int a[n];
	printf("请输入数组数据:\n");
	for(int i=0;i<n;i++)
	  scanf("%d",&a[i]);
	int max;
	max=MaxSubArray(a,n);
	printf("最大子数组和为:%d\n",max);
}

1.1.2 分治法

将数组从中间分开,那么最大子数组要么完全在左半边数组,要么完全在右半边数组,要么跨立在分界点上。
完全在左右数组,递归解决。
跨立在分界点上:实际上是左数组的最大后缀和右数组的最大前缀的和。因此,从分布点向前扫,向后扫即可。
代码:

#include <stdio.h>
#include <math.h>

#define max(a,b) (a>b)?a:b
int max2(int a,int b,int c) 
{
	int big;
	if(a >= b)
	  big = a;
	else 
	  big = b;
	if(c> big)
	  big = c; 
	return big;
 } 

int MaxSub(int a[],int from,int to)
{
	if(to==from)
	   return a[from];
	   
	int mid=(from+to)/2;
	int m1=MaxSub(a,from,mid);
	int m2=MaxSub(a,mid-1,to);
	
	int i,left=a[mid],now=a[mid];
	for(i=mid-1;i>=from;i--)
	{
		now+=a[i];
		left=max(now,left); 
	}
	int right=a[mid+1];
	now=a[mid+1];
	for(i=mid+2;i<=to;i++)
	{
		now+=a[i];
		right=max(now,right);
	}
	int m3=left+right;
	return max2(m1,m2,m3);
}

int main()
{
	printf("请输入数组个数:\n");
	int n;
	scanf("%d",&n);
	int a[n];
	printf("请输入数组数据:\n");
	for(int i=0;i<n;i++)
	  scanf("%d",&a[i]);
	int max;
	max=MaxSub(a,0,n);
	printf("最大子数组和为:%d\n",max);
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值