编程之美 2.14 数组的子数组之和的最大值 扩展题2

来源:互联网 发布:淘宝网买运动鞋 编辑:程序博客网 时间:2024/05/17 03:58
#include <stdio.h>#include <stdlib.h>#include <memory.h>#define MAX 20int main(){int n,i;int a[MAX];freopen("214.in","r",stdin);while(scanf("%d",&n) && n!=0){memset(a,0,sizeof(a));for(i=0;i<n;++i)scanf("%d",&a[i]);int max=a[0];//子集和最大值int beg=0;//最大子集和数组的起点下标int end=0;//最大子集和数组的起点下标int f=a[0];//表示以当前点为末尾子集和的最大值int f_beg=0;//表示以当前点为末尾最大值的子集和的起点for(i=1;i<n;++i){if(f<=0){f=a[i];if(f>max){//更新max=f;beg=i;end=i;f_beg=i;//更新起点}}else{f=f+a[i];if(f>max){max=f;beg=f_beg;end=i;}}}printf("max='%d' ,beg='%d' ,end='%d'\n",max,beg,end);}    return 0;}

测试数据:

6
1 -2 3 5 -3 2
6
0 -2 3 5 -1 2
5
-9 -2 -3 -5 -3
0

基本思路:动态规划,设f[i]表示以第i个数据为结尾的子数组和的最大值,则可以得到递推:if f[i-1]<=0 则 f[i]=a[i],否则f[i]=f[i-1]+a[i]。需要O(n)的空间复杂度,观察f[i]只依赖于f[i-1],因此可以考虑用一个变量表示以当前节点为末尾的子数组和的最大值(f),可以将复杂度将为O(1)。并且在遍历过程中记录最大子集和的值(max)、起点(beg)、终点下标(end)。为了更新beg,还需要记录当前节点为末尾的最大子集和f的起点f_beg。

 


 

原创粉丝点击