【HDU】 1003 Max Sum

来源:互联网 发布:mindmap中文版软件 编辑:程序博客网 时间:2024/06/06 17:54

Max Sum


  • 题目链接
    Max Sum

  • 题目大意

给你一串数,正的负的都有,现在要你算出这一列数的最大子段和(就是选取一段连续的部分,这部分所有的数加起来的和是所有情况中最大的)。


  • 题解

这一题我首先想到的是用合并的方法,比如一串数,最大子段和只有可能有三种情况:
1.包含最左边的数。
2.包含最右边的数。
3.中间的某一段。
在这里,我采用递推的思路去分析1~i和1~i+1。发现第一种情况其实没必要考虑….所以在这里我们就只有2种情况要考虑了——包含最右边的情况和中间的情况。

我们用max1表示中间某一段的最大子段和(就是我们的解),用max2表示包含最右边的数的最大子段和。所以在求解1~i+1的解时,我们先用max2+a[i+1],如果这个数是正数,我们就与max1比较且予以保留,如果这个数是负数,我们先比较,然后把max2清0(因为如果max2是负数的话会影响到我们后面的解,这里不太好说,具体体会吧…)

还有一点,关于很多人说这是DP,个人感觉只是一个递推而已,并没有明显的决策。


  • 代码
#include <iostream>#include <cstring>#include <cstdio>using namespace std;int a[100005],T,n;int main(){    int t;    scanf("%d",&T);    t=T;    while (T--)    {        memset(a,0,sizeof(a));        scanf("%d",&n);        for (int i=1;i<=n;i++) scanf("%d",&a[i]);        int max1=a[1],max2=0,s1=1,e=1,s2=1;        for (int i=1;i<=n;i++)        {            max2+=a[i];            if (max2>max1)            {                max1=max2;                s2=s1; e=i;            }            if (max2<0)            {                max2=0;                s1=i+1;            }        }        printf("Case %d:\n",t-T);        printf("%d %d %d\n",max1,s2,e);        if (T) printf("\n");    }    return 0;}
0 0
原创粉丝点击