您的位置:首页 > 编程语言

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

2013-05-13 10:41 190 查看
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#define MAX 20
int 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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐