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

给定由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. 创建一个长度与输入数组相同的动态规划数组dp,初始化dp为输入数组的第一个元素。 2. 从数组的第二个元素开始遍历,对于当前位置i,将dp[i-1]与0相比较,如果dp[i-1]大于0,则将其加上当前元素nums[i]更新为dp[i],否则将dp[i]更新为当前元素nums[i]。 3. 在遍历过程中,同时记录最大的段和maxSum,每次更新dp[i]时,也更新maxSum为dp[i]和maxSum中的较大值。 4. 遍历完整个数组后,maxSum即为最大的段和。 这种方法的时间复杂度为O(n),其中n是输入数组的长度。 举个例,假设输入数组为[-2, 1, -3, 4, -1, 2, 1, -5, 4],按照上述步骤进行动态规划解锁最大段和问题的计算: 1. 初始化dp为-2。 2. 遍历数组,对于位置1,dp为max(dp+nums, nums),即1;对于位置2,dp为max(dp+nums, nums),即-2;对于位置3,dp为max(dp+nums, nums),即4;对于位置4,dp为max(dp+nums, nums),即3;对于位置5,dp为max(dp+nums, nums),即5;对于位置6,dp为max(dp+nums, nums),即6;对于位置7,dp为max(dp+nums, nums),即1;对于位置8,dp为max(dp+nums, nums),即5。 3. 在遍历过程中,最大段和maxSum的值分别为-2, 1, 1, 4, 4, 5, 6, 6, 6,最终maxSum为6。 所以,使用动态规划解锁最大段和问题的结果为6。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值