51nod_1049 最大子段和(简单DP)

来源:互联网 发布:淘宝店铺装修尺寸 编辑:程序博客网 时间:2024/06/06 04:18

1049 最大子段和
基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 取消关注
N个整数组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的连续子段和的最大值。当所给的整数均为负数时和为0。
例如:-2,11,-4,13,-5,-2,和最大的子段为:11,-4,13。和为20。
Input
第1行:整数序列的长度N(2 <= N <= 50000)
第2 - N + 1行:N个整数(-10^9 <= A[i] <= 10^9)
Output
输出最大子段和。
Input示例
6
-2
11
-4
13
-5
-2
Output示例
20

思路:简单的动态规划
可以用状态转移方程:dp[i]=max(a[i],dp[i-1]+a[i])
也可以:记录字段和sum,线性扫数组,如果sum>0(即sum能使i位置的最大值增大),sum+=a[i]
否则sum=a[i]
maxn=max(maxn,sum)
而最大值maxn 就是 sum的峰值

代码:

#include<stdio.h>#include<iostream>#include<stdlib.h> using namespace std;long long a[50005];long long dp[50005];long long maxSum(int n){    long long maxn,sum;    sum=0;    for(int i=1;i<=n;i++){        if(sum>0){            sum+=a[i];        }        else{            sum=a[i];        }        maxn=max(maxn,sum);    }    return maxn;}int main(){    int n;    cin>>n;    int cns=0;    for(int i=1;i<=n;i++){       scanf("%I64d",&a[i]);        if(a[i]<=0)        cns++;    }    if(cns==n){        cout<<0<<endl;        return 0;    } printf("%I64d\n",maxSum(n));    return 0;}   // dp[0]=0;    // for(int i=1;i<=n;i++){    //     dp[i]=a[i]>(a[i]+dp[i-1])?a[i]:(a[i]+dp[i-1]);    //  }    //  long long max=0;    //  for(int i=1;i<=n;i++){    //      max=max>dp[i]?max:dp[i];    //  }
0 0