思路:
- 暴力求解--把所有的子集求和进行比较,记录值为最大的子集,时间复杂度为O(n^3)
- 动态规划--时间复杂度为O(n)
//数组最大连续子集
//例如{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)
//暴力枚举O(n^3) 动态规划O(n)
//假设最大和子数组由两部分组成,一个是前向和sum,另一个部分就是前向和sum的下一个元素
//如果sum的值小于0就意味着它不可能成为最大子数组的一部分了
//因此必须舍弃之前的sum,重新定义新的sum,这个sum的起始元素就是之前sum和序列的下一个元素
//动态规划法简洁明了,时间复杂度仅为O(n),减少了求解次数。
#include<stdio.h>
#define n 8
int main() {
int a[n],i,j,sum,max,si,ei;//si开始下标,ei结束下标
for(i=0; i<n; i++) {
scanf("%d",&a[i]);
}
i=0;
j=0;
si=0;
ei=0;
max=a[0];
sum=a[0];
while(j<n) {
if(sum<0) {
j++;
i=j;//新起点为之前sum和序列的下一个元素(j为上一个序列的结尾)
sum=a[i];
} else {
if(sum>max) {
max=sum;
si=i;
ei=j;
}
j++;
if(j<n) sum=sum+a[j];
}
}
printf("最大连续子集和=%d,开始下标=%d,结束下标=%d,共%d个元素\n",max,si,ei,ei-si+1);
for(i=si;i<=ei;i++){
printf("%d ",a[i]);
}
return 0;
}