动态规划——最大子段和

最大字段和这是动态规划的经典问题,上一讲我们讲了一个简单的动态规划问题,这个最大子段和也不难,我们主要通过这几个简单的问题来了解一下动态规划。还有最大子段和用分治法也能做,等到日后我们在讲。


问题描述:给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。

当所给的整均为负数时定义子段和为0。


解决思路:

之前说个,动态规划解决问题是自底向上。原问题的规模是n个元

素。这n个元素不好考虑,我们先考虑n-1个元素,这样还不好考

虑,我们考虑n-2个元素,这样依次递减,最后问题规模变成一个

元素。但是我们发现,在递减的过程中间,子问题的最优解包含

在原问题的最优解之中,而且子问题的解还有一些是重复的。

因此,使用动态规划来解决这个问题。

就像上一篇博客中讲到的,我们要写出一个递归方程。我们设置一个数组b来存放最优解,首先将b[1]=a[1],a存放的是我们的n个元素。第i个元素,他的状态就是将他放不放到数组b中(和之前的有些像)。因此,递归方程就是:b[i]=max{b[i-1]+a[i],a[i]}.

例如:

有一组数
,

-2 5 4 -3 7
的最大子段和是
13,
是从
5

7.

代码:

#include <stdio.h>
#define N 100
int a[N];

int main()
{
	int i,n,b[N],max;
  while(scanf("%d",&n)&&n!=0)
  {
  for(i=1;i<=n;i++)
	  scanf("%d",&a[i]);
  b[1]=a[1];
  for(i=2;i<=n;i++)
	{
	if(b[i-1]>0)
		b[i]=b[i-1]+a[i];
	else
		b[i]=a[i];
	}
  max=b[1];
  for(i=1;i<=n;i++)
	  if(max<b[i])
		  max=b[i];
	printf("%d\n",max);
  }	
        return 0;
}

在这里,我们如果要求输出是那些数,我们该怎么办??

我们只需要在设置一个数组c,来存放是那些书构成了最大子段和。当将i放入b中的时候,我们就将对应的i放入c,最后输出c就可以了。代码就不写了,望各位自己实现!

    原文作者:动态规划
    原文地址: https://blog.csdn.net/jin_syuct/article/details/49389645
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞