最大子段和

定义

给定一个由数字组成的序列,其中连续的一段子序列称为一个子段,子段中的所有数之和称为子段和,这里只考虑非空子段即至少包含—个元素的子段。

动态规划算法

对于全是非正数的序列,答案明显就是其中的元素的最大值。

对于有正数的序列,考虑以每一个点为结尾的最大子段和,这个子段一定满足其前缀和均非负,因为如果有一个前缀是负的,那么减掉这个前缀对于这个点一定更优,并且这个子段要尽量往前延伸。

所以我们可以只用一次扫描,记录目前统计的和sum以及答案ans。当sum加上当前位置这个数还是正数的时候就继续累加sum,否则就将sum置为0。这样就舍掉了所有前缀是负数的情况,并且保证了这个子段尽可能的长了,也就是说扫描中记录的sum就是以每一个点为结尾的最大子段和,每一次如果sum比ans大就可以更新ans。最后ans就是整体的最大子段和。

时间复杂度O(N).

int a[10005];
int sum;
int n;
int ans;
int main(){
	cin >> n;
	for(int i = 0; i < n; i++){
		cin >> a[i];
		ans = max(ans, a[i]);
	}
	if(ans <= 0) cout << ans;//先考虑全为非正数的情况,如果不考虑,用这种方法就会出错
	else {
		for(int i = 0; i < n; i++){
			sum += a[i];
			if(sum < 0) sum = 0;
			ans = max(ans, sum);
		}
		cout << ans;
	}
	return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值