# 题目

Problem Description

Given a sequence a[1],a[2],a[3]……a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14.

Input

The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line starts with a number N(1<=N<=100000), then N integers followed(all the integers are between -1000 and 1000).

Output

For each test case, you should output two lines. The first line is “Case #:”, # means the number of the test case. The second line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence. If there are more than one result, output the first one. Output a blank line between two cases.

Sample Input

2
5 6 -1 5 4 -7
7 0 6 -1 1 -6 7 -5

Sample Output

Case 1:
14 1 4

Case 2:
7 1 6

# 题解

## 朴素算法：时间复杂度O(N ^ 3)

#include <stdio.h>
#define LEN 100010
#define MAXNUM 1001

int array[LEN];

int main(void){
int T = 0;
scanf("%d", &T);

for(int kase = 1; kase <= T; kase++){
int n = 0;
scanf("%d", &n);

for(int i = 0; i < n; i++)
scanf("%d", &array[i]);

int maxSum = -MAXNUM, start = 0, end = 0;
for(int i = 0; i < n; i++)
for(int j = i; j < n; j++){
int thisSum = 0;

for(int k = i; k <= j; k++)
thisSum += array[k];

if(thisSum > maxSum){
maxSum = thisSum;
start = i; end = j;
}
}

printf("Case %d:\n", kase);
printf("%d %d %d\n", maxSum, start + 1, end + 1);
printf(kase == T ? "" : "\n");
}

return 0;
}

## 进阶算法：时间复杂度O(N ^ 2)

#include <stdio.h>
#define LEN 100010
#define MAXNUM 1001

int array[LEN];

int main(void){
int T = 0;
scanf("%d", &T);

for(int kase = 1; kase <= T; kase++){
int n = 0;
scanf("%d", &n);

for(int i = 0; i < n; i++)
scanf("%d", &array[i]);

int maxSum = -MAXNUM, start = 0, end = 0;
for(int i = 0; i < n; i++){
int thisSum = 0;

for(int j = i; j < n; j++){
thisSum += array[j];

if(thisSum > maxSum){
maxSum = thisSum;
start = i; end = j;
}
}
}

printf("Case %d:\n", kase);
printf("%d %d %d\n", maxSum, start + 1, end + 1);
printf(kase == T ? "" : "\n");
}

return 0;
}

## 最终算法：时间复杂度O(N)

#include <stdio.h>
#define MAXNUM -1001
int main(void){
int T = 0;
scanf("%d", &T);

for(int kase = 1; kase <= T; kase++){
int n = 0;
scanf("%d", &n);

int thisSum = 0, maxSum = MAXNUM;
int start = 1, end = 1, startPosition = 1;

for(int i = 1; i <= n; i++){
int num = 0;
scanf("%d", &num);

thisSum += num;
if(thisSum > maxSum){
maxSum = thisSum;
start = startPosition;
end = i;
}
if(thisSum < 0){
thisSum = 0; // 重置thisSum以开始下一个连续子序列的查找
startPosition = i + 1; // 存储下一个连续子序列的开始位置
}
}

printf("Case %d:\n", kase);
printf("%d %d %d\n", maxSum, start, end);
printf(kase == T ? "" : "\n");
}

return 0;
}

!> MAXNUM的值很重要。只有大于MAXNUM的值会在判断过程中参与判断。因为maxSum在算法运行过程中只会更大而不会更小，从而若序列中有小于MAXNUM的元素，则该元素根本无法进入判断流程。当MAXNUM的值被设为0时问题会尤为显著：一切负数元素都会被忽略，则若序列如同-1, -2, -3, -4, -3, -5一般全由负数元素构成，则算法最后会给出最大子序列和为0。

x> startPosition变量的作用。为什么不能这样改写程序：

if(thisSum > maxSum){
maxSum = thisSum;
end = i;
}
if(thisSum < 0){
thisSum = 0;
start = i + 1;
}