最大字段和(动态规划)

题目描述

给定由n个整数(包含负整数)组成的序列a1,a2,…,an,求该序列子段和的最大值。
当所有整数均为负值时定义其最大子段和为0。
所求的最优值为:
在这里插入图片描述

例如,当(a1,a2, ……a7,a8)=(1,-3, 7,8,-4,12, -10,6)时,最大子段和为:
在这里插入图片描述
在这里插入图片描述

计算最优值
#define NUM 1001
int a[NUM];
int MaxSum(int n)
{
	int sum=0; 
	int b=0;
	for (int i=1;i<=n;i++)
	{
		if (b>0) b+=a[i]; else b=a[i];
		if (b>sum) sum=b;
	}
	return sum;
}

令besti,bestj为最大子段和sum的起始位置和结束位置;
在当前位置i,如果b[i-1] ≤0时,在取b[i]=a[i] 的同时,保存该位置i到变量begin中,显然:
当b(i-1)≤0时,begin=i;
当b(i)≥sum时,besti=begin,bestj=i。
在这里插入图片描述

计算最优解
#define NUM 1001
int a[NUM];
int MaxSum(int n, int &besti, int &bestj)
{
  int sum=0; 
  int b=0;
  int begin = 0;
  for (int i=1; i<=n; i++)
  {
	if (b>0)  b+=a[i]; 
	else {b=a[i]; begin = i;}
 	if (b>sum) //得到新的最优值时,更新最优解
	{
	  sum = b; 
	  besti = begin; 
	  bestj = i;
	}
  }
  return sum;
}
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值