HDU-1003 Max Sum(动态规划,最长字段和问题)

来源:互联网 发布:热负荷计算软件 编辑:程序博客网 时间:2024/05/26 12:54

Max Sum

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 193355 Accepted Submission(s): 45045

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

这是线性动态规划比较简单的最长子段和的问题,状态转移方程
if(dp[i-1]>=0)
dp[i]=dp[i-1]+a[i];
else
{
dp[i]=a[i];
}
这道题目可以用数组,也可以用滚动数组的效果,节省空间、

用一维数组

#include <iostream>#include <algorithm>#include <string.h>#include <math.h>#include <stdlib.h>using namespace std;int n;int a[100005];int dp[100005];int start;int _end;int main(){    int t;    scanf("%d",&t);    for(int cas=1;cas<=t;cas++)    {        scanf("%d",&n);        for(int i=1;i<=n;i++)        {            scanf("%d",&a[i]);        }        memset(dp,0,sizeof(dp));        _end=1;        dp[1]=a[1];        for(int i=2;i<=n;i++)        {              if(dp[i-1]>=0)                  dp[i]=dp[i-1]+a[i];              else              {                  dp[i]=a[i];              }        }        int max=dp[1];        for(int i=2;i<=n;i++)        {            if(max<dp[i])            {                max=dp[i];                _end=i;            }        }        int t1=0;        start=_end;        for(int i=_end;i>0;i--)        {            t1=t1+a[i];            if(t1==max)                start=i;        }        cout<<"Case "<<cas<<":"<<endl<<max<<" "<<start<<" "<<_end<<endl;        if(cas!=t)            printf("\n");    }    return 0;}

滚动数组

#include <iostream>#include <algorithm>#include <string.h>#include <math.h>#include <stdlib.h>using namespace std;int n;int a;int sum;int _begin;int _end;int main(){    int t;    scanf("%d",&t);    int k=0;    while(t--)    {        int max;        int x=1;        scanf("%d%d",&n,&a);        sum=a;        max=a;        _begin=_end=1;        for(int i=2;i<=n;i++)        {            scanf("%d",&a);            if(sum>=0)            {                sum+=a;            }            else            {                sum=a;                x=i;            }            if(max<sum)            {                max=sum;                _begin=x;                _end=i;            }        }          cout<<"Case "<<++k<<":"<<endl<<max<<" "<<_begin<<" "<<_end<<endl;         if(t)            cout<<endl;    }    return 0;}
0 0
原创粉丝点击