算法设计——最大子段和(动态规划)

问题

给定由n个整数(包含负整数)组成的序列a1,a2,…,an,求该序列子段和的 最大值。当所有整数均为负值时定义其最大子段和为0。

**举个栗子:**当(a1,a2, a3, a4, a5,a6)=(-2,11,-4,13,-5,-2)时,最大子段和为:11-4+13=20

一个简单算法

我们可通过循环来找到最大的和
在这里插入图片描述
当字段的开始下标确定后,若 要计算[i:j]的字段和可以利用 上一次计算的[i:j-1]的字段

改进

在这里插入图片描述
我们发现这个题可以用分治来进行

分治算法

如果将所给的序列a[1:n]分为长度相等的两段a[1:n/2]和 a[n/2+1:n],分别求出这两段的最大子段和,则a[1:n]的最大子段 和有三种情形:
A. a[1:n]的最大子段和与a[1:n/2]的最大子段和相同;
B. a[1:n]的最大子段和与a[n/2+1:n]的最大子段和相同;
C. a[1:n]的最大子段和为下面的形式。
在这里插入图片描述
得到下面算法
在这里插入图片描述

动态规划算法

bj表示从a1到aj(前 j 项)中,包含aj的最大的子段和
由bj的定义易知,当bj-1>0 时bj=bj-1+aj,否则bj=aj。
由此可得计算bj的动态规划递归式bj=max{bj-1+aj,aj},1≤j≤n。

代码实现

#include<stdio.h>
int main()
{
	 int a[101];
	 int sum,i,n,b=0;
	 scanf("%d",&n);
	 for(i=1;i<=n;i++){
	 	scanf("%d",&a[i]); //输入数据 
	 } 
	 for(i=1;i<=n;i++){
	 	if(b<0){
	 		b=a[i];
		}else{
			b+=a[i];	
		}
		if(sum<b) {
			sum=b;
		}
	 }
	 printf("%d\n",sum);
	 return 0;
 } 
  • 14
    点赞
  • 89
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值