/*
连续子数组的最大和:
输入一个整形数组,数组里有整数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的
最大值。要求时间复杂度为O(n)。
分析:
刚开始令sum = 0,
f[i] = {iArr[i],i = 0 或者f(i-1) <= 0
{f(i-1) + iArr[i],i != 0 并且 f(i-1) > 0
动态规划:用f[i]表示以第i个数结尾的最大连续和
如果以第i-1个数字结尾的子数组的数字和小于0,如果把这个负数与第i个数字相加,结果肯定比第i个
数字本身要小,因此此时就令其为当前数字。
如果以第i-1个数字结尾的最大连续和大于0,此时加上第i个数字(不管第i个数字是否为正或为负)
加起来的和必定比第i个数字要大
输入:
输入有多组数据,每组测试数据包括两行。
第一行为一个整数n(0<=n<=100000),当n=0时,输入结束。接下去的一行包含n个整数(我们保证所有整数属于[-1000,1000])。
输出:
对应每个测试案例,需要输出3个整数单独一行,分别表示连续子向量的最大和、该子向量的第一个元素的下标和最后一个元素的下标。若是存在多个子向量,则输出起始元素下标最小的那个。
样例输入:
3
-1 -3 -2
5
-8 3 2 0 5
8
6 -3 -2 7 -15 1 2 2
0
样例输出:
-1 0 0
10 1 4
8 0 3
*/
/*
关键:
1 f[i] = {iArr[i],i = 0 或者f(i-1) <= 0
{f(i-1) + iArr[i],i != 0 并且 f(i-1) > 0
动态规划:用f[i]表示以第i个数结尾的最大连续和
2 要保存当前的累加和与之前的最大累加和进行比较
if(lSum > lMaxSum)
*/
#include <stdio.h>
#include <string.h>
const int MAXSIZE = 100001;
int iArr[MAXSIZE];
void maxSubArrSum(int n)
{
long long lSum = 0,lMaxSum = iArr[0];
int iNewBegIndex = 0,iNewEndIndex = 0;
int iBegIndex = 0,iEndIndex = 0;
for(int i = 0 ; i < n ; i++)
{
if(lSum <= 0)
{
lSum = iArr[i];//这里需要重新记录最大连续子数组的起始下标
iNewBegIndex = i;
}
else
{
lSum += iArr[i];
iNewEndIndex = i;
}
if(lSum > lMaxSum)
{
lMaxSum = lSum;
iBegIndex = iNewBegIndex;//更新最大连续子数组的起始下标
iEndIndex = iNewEndIndex;
}
}
printf("%lld %d %d\n",lMaxSum,iBegIndex,iEndIndex);//注意是:%lld,而不是%d
}
void process()
{
int n;
while(EOF != scanf("%d",&n))
{
if(n == 0)
{
break;
}
if( n < 0 || n >= MAXSIZE)
{
continue;
}
memset(iArr,0,sizeof(iArr));
for(int i = 0 ; i < n ;i++)
{
scanf("%d",&iArr[i]);
}
maxSubArrSum(n);
}
}
int main(int argc,char* argv[])
{
process();
getchar();
return 0;
}