HDU 1003 Max Sum (动态规划 最大区间和) 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 4

Case 2:
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<bits/stdc++.h>

using namespace std;

int T,n,i,dp[100005],l,r,s,maxs,t=0;

int main()
{
    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:
",t);
        printf("%d %d %d
",maxs,l,r);    
        if(T)
        printf("
");
    }
}