要找出和最大的子段,首先想到的是枚举,枚举的方法是,分别将数串中的每一个数作为子段的第一位数,然后子段长度依次递增。例如:
(2,-3,4,-1)这个数串枚举的所有情况为:
以2作为子段的第一位: 2,(2,-3),(2,-3,4),(2,-3,4,-1)。
以-3作为子段的第一位: -3,(-3,4),(-3,4,-1)。
以4作为子段的第一位: 4,(4,-1)。
以-1作为子段的第一位: -1 。
从枚举的过程中发现:
当前子段和的值为负值时,就没必要再往下进行,而应将下一
位数作为子段的第一位。也就是说,当处理第i个数时,如果以第i-1个数为结尾的子段的和为正数,则不必将第i个数作为新子段的首位进行枚举,因为新子段加上前面子段和所得的正数,一定能得到更大的子段和
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
int t;cin>>t;
for(int i=1;i<=t;i++){
int n;cin>>n;int sta,finish,position=1;
int maxsum=-1010,pre=0;
for(int j=1;j<=n;j++){
int tt;cin>>tt;
pre+=tt;
if(pre>maxsum){
maxsum=pre;
finish=j;
sta=position;
}if(pre<0){
pre=0;
position=j+1;
}
}
printf("Case %d:\n%d %d %d\n",i,maxsum,sta,finish);
if(i!=t)cout<<endl;
}
}