这道题是2004年浙江大学计算机专业考研复试真题
输出部分除了要求输出最大子列和之外,还要输出最大子列和的起始位置和结束位置
Given a sequence of K integers { N1, N2, ...,NK}. A continuous subsequence is defined to be { Ni, Ni+1, ..., Nj} where 1≤i≤j≤K. The Maximum Subsequence is the continuous subsequence which has the largest sum of its elements. For example, given sequence { -2, 11, -4, 13, -5, -2 }, its maximum subsequence is { 11, -4, 13 } with the largest sum being 20.
Now you are supposed to find the largest sum, together with the first and the last numbers of the maximum subsequence.
给出一个含有K个整数的序列{N1, N2, ...,NK},将一个连续的子序列定义为{Ni,Ni+1, ...,Nj},其中1≤i≤j≤K。最大子列和是指元素之和最大的连续子序列。例如,给出一个序列{ -2, 11, -4, 13, -5, -2 },它的最大子列为{ 11, -4, 13 },其和为20。现在,要求找到最大子列和以及最大子序列的第一个和最后一个数字。
Input Specification:[输入说明]
Each input file contains one test case. Each case occupies two lines. The first line contains a positive integer K(≤10000). The second line contains K numbers, separated by a space.
每个输入文件包含一个测试用例。每个用例占两行。第一行包含一个正整数K(≤10000),第二行包含K个数字,中间用空格隔开。
Output Specification:[输出详细说明]
For each test case, output in one line the largest sum, together with the first and the last numbers of the maximum subsequence. The numbers must be separated by one space, but there must be no extra space at the end of a line. In case that the maximum subsequence is not unique, output the one with the smallest indices i and j(as shown by the sample case). If all the K numbers are negative, then its maximum sum is defined to be 0, and you are supposed to output the first and the last numbers of the whole sequence.
对于每个测试用例,输出一行最大和值以及最大子序列的第一个数字和最后一个数字。这些数字必须被空格隔开,行末不允许有额外的空格。为了放置最大子序列不是唯一的,则输出下标i和j最小的一个(如样例所示)。如果K个数都是负数,那么最大和值规定为0,要求输出整个序列的第一个数字和最后一个数字。
Sample Input:[样例输入]
10
-10 1 2 3 4 -5 -23 3 7 -21
Sample Output:[样例输出]
10 1 4
程序实现
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 const int maxn = 1e4+100; 7 8 int dp[maxn], fa[maxn];//dp[i]表示以i结尾的最大值, fa[i]表示以i右端点所对应的左端点 9 int a[maxn]; 10 11 int main(){ 12 int n,i; 13 while(scanf("%d", &n) != EOF){ 14 for(i = 1; i <= n; i++) 15 scanf("%d", &a[i]); 16 dp[0] = -1; //我们把0设为负数是为了让第一个点取到它自己 17 for(i = 1; i <= n; i++){ 18 if(dp[i-1] < 0){ 19 fa[i] = i; 20 dp[i] = a[i]; 21 } 22 else{ //如果以前面一位为结尾的最大连续和是大于0的,那么第i位肯定接着第i-1位 23 dp[i] = dp[i-1] + a[i]; 24 fa[i] = fa[i-1]; 25 } 26 } 27 int flag = 0, Max = -1e9; 28 for(i = 1; i <= n; i++) 29 if(dp[i] > Max) flag = i, Max = dp[i]; 30 if(Max < 0) 31 printf("0 %d %d\n",a[1],a[n]); //如果Max1最后小于0,说明1到n位置上的所有数都为负数,直接输出结果即可 32 else 33 printf("%d %d %d\n", Max, a[fa[flag]], a[flag]); //否则的话输出最大值,左端点右端点 34 } 35 return 0; 36 }
运行结果:
含有两个最大子序列的情况下,选择输出下表较小的那一个
当K个数全为负数的情况
参考链接:http://blog.csdn.net/plank_root/article/details/52578982