Max Sum
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 330535 Accepted Submission(s): 78678
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 4Case2:7 1 6
题目大意与分析
就是给你一个序列,求最大区间和以及该最大区间的下标
动态规划的思想:
用dp[i]来代表以a[i]为结尾的最大区间和,这样就有两种情况:
要么dp[i]是正的 那么以a[i]结尾的最大区间和就是dp[i-1]+a[i](因为必须是a[i]结尾,a[i]是正是负都无法取舍的)
要么dp[i]是负的 那么以a[i]结尾的最大区间和就是a[i]
状态转移方程:dp[i] = max( dp[i-1]+a[i], a[i] );
初始化:因为我们从前往后推,可以将dp数组和a数组合二为一,节约空间
另外需要注意的是 需要三个游标:s、l、r 分别代表当前区间的左端点、最大区间的左端点、最大区间的右断点,至于当前区间的右端点,可以直接用i表示。
代码
#include
using namespacestd;int T,n,i,dp[100005],l,r,s,maxs,t=0;intmain()
{
cin>>T;while(T--)
{
t++;
memset(dp,0,sizeof(dp));
cin>>n;for(i=1;i<=n;i++)
{
scanf("%d",&dp[i]);
}
maxs=dp[1];
s=1;
l=1;
r=1;for(i=2;i<=n;i++)
{
dp[i]=max(dp[i-1]+dp[i],dp[i]);if(dp[i-1]<0)
{
s=i;
}if(dp[i]>maxs)
{
l=s;
r=i;
maxs=dp[i];
}
}
printf("Case %d:\n",t);
printf("%d %d %d\n",maxs,l,r);if(T)
printf("\n");
}
}