最大子段和问题

最大子段和

问题描述:
给定由n个整数(包含负整数)组成的序列a1,a2,...,an,求该序列子段和的最大值。

当所有整数均为负值时定义其最大子段和为0。
依此定义,所求的最优值为:
 
例如,当(a1,a2 , a3 , a4 , a5 ,a6)=(-2,11,-4,13,-5,-2)时,

最大子段和为:

11+(-4)+13 =20

解:

最大字段和:
一层循环:动态规划,循环从0~n-1,代表最大子段和的字段的结束位置。使用temp作为当前和的暂定值,
如果temp+a[i]<0则代表最大字段的开始位置可能从i开始,但也有可能不是,
当temp>sum的时候,做交换。
二层循环:第一层循环代表字段的开始位置,第二层循环代表字段的结束位置,temp标记依次加a[j]
当temp>sum时候,就交换,并且记住当前的i和j,作为起始位置
三层循环:暴力寻找, 第一层循环代表字段的开始位置,第二层循环代表字段的结束位置,第三层循环做相应的加法

#include <stdio.h>
int n;
int a[100];

void  first()
{//一层循环 
	int sum=0;
	int temp=0;
	for(int i=0;i<n;i++)
	{
		if(temp + a[i]<0){
			temp=0;
		}
		else
			temp+=a[i];
		if(temp>sum){
			sum=temp;
		}
	}
	printf("%d\n",sum);
}
void  second()
{//两层循环 
	int sum=0;
	int ii,jj;
	for(int i=0;i<n;i++)
	{
		int temp=0;
		for(int j=i;j<n;j++)
		{
			temp+=a[j];
			if(temp>sum){ 
				sum=temp;
				ii=i;jj=j; 
			} 
		 } 
	}
	printf("%d->%d\n",ii,jj);
	printf("%d\n",sum);
}
void  third()
{//三层循环 
	int sum=0;
	int ii,jj;
	for(int i=0;i<n-1;i++)
	{
		for(int j=i;j<n;j++)
		{
			int temp=0;
			for(int k=i;k<=j;k++)
			{
				temp+=a[k];
			}
			if(temp>sum){
				sum=temp;
				ii=i;jj=j;
			}
		}
	}
	printf("%d->%d\n",ii,jj);
	printf("%d\n",sum);
}

int main()
{
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
	}
	printf("one:\n");
	first();
	printf("two:\n");
	second();
	printf("three:\n");
	third();
	return 0;
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值