动态规划——最大子段和

来源:互联网 发布:珠江新闻眼回看软件 编辑:程序博客网 时间:2024/05/16 17:46

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


问题描述:给定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,是从57.

代码:

#include <stdio.h>#define N 100int 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];elseb[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就可以了。代码就不写了,望各位自己实现!



0 1
原创粉丝点击