主要是通过动态规划来做这道题。
我认为,我们可以假设当前位置是已选到最大的子串结束位置。
如果之前的最大子串和为负数,那么其对最终和没有正面意义,那么就将其舍去,设置start与end于新位置p。
如果之前和为正数,往后看,end++。若子串以p结尾,无论a[p]是正是负,以p结尾的最大子串和定是a[0]~a[p]最大子串和+a[p],我们将其与历史最大子串和相比较,若它比历史最大子串和还要大,那么就将历史最大子串信息用这个新子串信息替换。若它比历史最大子串和小,则继续往后找。
问题大概是这样,贴一下代码:
#include <stdio.h>
int main(int argc, const char * argv[]) {
int T,i;
scanf("%d",&T);
for(i=0;i<T;i++){
int n,p;
scanf("%d",&n);
int a[100000];
for(p=0;p<n;p++){
scanf("%d",&a[p]);
}
int start=0,end=-1,endmax=-10000000,maxhere=0;
int fstart=0,fend=0;
for(p=0;p<n;p++){
if(maxhere<0){
maxhere=a[p];
start=p;
end=p;
}else{
maxhere+=a[p];
end++;
}
if(maxhere>endmax){
endmax=maxhere;
fstart=start;
fend=end;
}
}
printf("Case %d:\n",i+1);
printf("%d %d %d\n",endmax,fstart+1,fend+1);
if(i!=T-1){
printf("\n");
}
}
return 0;
}
这里注意一点,end初始值要设置为-1,因为maxhere默认为0,end不可避免需要end++处理,但是第一次的位置end应该在0处,所以end需要设初始值-1。