思路:令dp[i]表示以a[i]结尾的连续子序列的最大相加和,分析以a[i+1]结尾的连续子序列的情况:
a[i+1]结尾的连续子序列有两种可能:
1)和以a[i]结尾的序列组成的新的序列;
2)只包含a[i+1]
1. dp[i]<0, 且是连续的子序列,则以a[i+1]结尾的连续子序列是第二种可能情况,序列中只有a[i+1],此时dp[i+1]=a[i+1]
2. dp[i]>=0, 则以a[i+1]结尾的连续子序列是第1种情况,是a[i]结尾的序列组成的新的序列, 此时dp[i+1]=dp[i]+a[i+1];
3. 题目的要求即就是求dp[i] (其中i=0…n)的最大值
import java.util.Scanner;
public class Main {
public static void main(String args[]) {
Scanner in = new Scanner(System.in);
while (in.hasNextInt()) {
int caseNum = in.nextInt();
for (int k = 0; k < caseNum; k++) {
int integerNum = in.nextInt();
int[] arr = new int[integerNum];
int length = arr.length;
int optSum = Integer.MIN_VALUE;
int start = 0;
int end = 0;
int caseIndex = k + 1;
int[] dp = new int[integerNum];
for (int j = 0; j < integerNum; j++) {
arr[j] = in.nextInt();
}
dp[0] = arr[0];
for (int i = 0; i < length - 1; i++) {
if (dp[i] < 0) {
dp[i + 1] = arr[i + 1];
start = i + 1;
} else {
dp[i + 1] = dp[i] + arr[i + 1];
}
}
optSum = dp[0];
end = 0;
for (int i = 1; i < length; i++) {
if (dp[i] > optSum) {
optSum = dp[i];
end = i;
}
// optSum = dp[i]>optSum?dp[i]:optSum;
// end = i;
}
int s = 0;
start = end;
for (int m = end; m >= 0; m--) {
s += arr[m];
if (s == optSum) {
start = m;
}
}
System.out.println("Case " + caseIndex + ":");
System.out.println(optSum + " " + (start + 1) + " " + (end + 1));
if (k < caseNum - 1) {
System.out.println();
}
}
}
}
}
Reference:
1. http://blog.csdn.net/ding_hai_long/article/details/20608783
2. http://blog.csdn.net/jecode/article/details/49954733