动态规则_最大子段和问题

给定由n个整数(可能为负数)组成的序列 a1 , a2 , ... , an
求该序列形如 for k = i to j : sum = sum + ak : next k
的子段和的最大值.

问题有很多解法,而用动态规则解是最简单的。

b[j] = max(1<=i<=j) { sum( i , j ) } , 1 <= j <= n

b[j] = max{ b[j-1] + a[j] , a[j] } , 1 <= j <= n

动态规则问题最重要的是得出
递归式
而这正是问题的难点,至少对我来说比较难

分析问题,找到问题是否有最优子结构,由最优子结构的性质得出
递归式



#include "iostream.h"

int MaxSum( int n , int *a , int &besti , int &bestj )
{
 int sum = 0;
 int begin = 0;
 int t = 0;

 besti = -1;
 bestj = -1;

 for( int i = 0 ; i < n ; i++ )
 {
  if( t > 0 )
  {
   t += a[i];
  }
  else
  {
   t = a[i];
   begin = i;
  }
  if( t > sum )
  {
   sum = t;
   besti = begin;
   bestj = i;
  }
 }
 return sum;
}

void main()
{
 int a[] = { -2 , 11 , -4 , 13 , -5 , -2 };
 int n = 6;
 int bi , bj;
 int best = MaxSum( n , a , bi , bj );
 cout<<"最大子段和为:"<<best<<endl;
 cout<<"起点 "<<bi<<" 终点 "<<bj<<endl;
}

参考资料:
 《计算机算法分析与设计》电子工业出版社
 程序有所改进

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值