最大连续子序列和问题
#include<stdio.h>
int main(){
int k;
scanf("%d",&k);
int a[k];
int i;
for(i=0; i<k; i++){
scanf("%d",&a[i]);
}
int maxsum=-1;
int sum=0;
int start=0;
int end=0;
int finalstart=0;
int flag=1;
for(i=0; i<k; i++){
if(a[i]>=0){
flag=0;
}
sum+=a[i];
if(sum<0){
sum=0;
start=i+1;
}else if(sum>maxsum){
maxsum=sum;
end=i;
finalstart=start;
}
}
if(flag){
finalstart=0;
end=k-1;
maxsum=0;
}
printf("%d %d %d",maxsum,a[finalstart],a[end]);
return 0;
}
题目中提到if all the numbers are negative, then its maximum sum is defined to be 0,所以不用考虑最大连续子序列和是负数的情况,我定义了一个flag变量用于检查是否所有数据均为负数。
我的想法是找分界点 i,最大连续子序列一定在分界点的两侧,i != 0 时,首先这个分界点一定<0,否则附近子序列加上分界点的值肯定会更大。然后任意一个在分界点前的子串加上分界点的值一定小于0(a[j]+a[j+1]+a[j+2]+…+a[i]<0),否则就可以继续往后加获得更大的连续子序列。
一个数组中可以存在多个分界点,但是最大连续子序列不可能跨过任何一个分界点,只要算出包含开头和结尾的每个分界点之间序列的和,并比较出最大的值,那个最大值便是最大连续子序列和。
根据之前分界点的第二个要求,可以写出求分界点的算法,不断计算sum,如果sum小于0,则寻找到了分界点,这时让记录开始的start变量指向分界点的后一位。若sum大于0,则比较sum与当前最大的maxsum,记录最大值同时确定两端的位置。