51nod 1049 最大子段和

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

预处理:前缀和last:上一个正数的位置dp[i]表示这个子段最后一个是i的最大和状态转移:如果前一个是非负数,dp[i]=dp[i-1]+a[i]否则,dp[i]=max(a[i],dp[last]+sum[i]-dp[last])
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int n;
long long a[50001],dp[50001],sum[50001];
int main()
{
    scanf("%d",&n);
    int last=0;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];
    for(int i=1;i<=n;i++)
    {
        if(a[i-1]>=0) dp[i]=dp[i-1]+a[i],last=i;
        else dp[i]=max(a[i],dp[last]+sum[i]-sum[last]);
    }
    long long ans=0;
    for(int i=1;i<=n;i++) ans=max(ans,dp[i]);
    printf("%lld",ans);
}
时间: 2024-10-25 15:59:17

51nod 1049 最大子段和的相关文章

[2016-05-09][51nod][1049 最大子段和]

时间:2016-05-09 19:04:34 星期一 题目编号:[2016-05-09][51nod][1049 最大子段和] 题目大意: N个整数组成的序列a[1],a[2],a[3],-,a[n],求该序列如a[i]+a[i+1]+-+a[j]的连续子段和的最大值.当所给的整数均为负数时和为0. 分析: 动态规划 dp[i]=max(dp[i?1]+a[i],a[i])dp[i]=max(dp[i?1]+a[i],a[i]) ans=max(dp[i])ans=max(dp[i]) 全部为负

1049 最大子段和

1049 最大子段和 基准时间限制:1 秒 空间限制:131072 KB 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) Outpu

最大字段和 51nod 1049 水水水水水水水水水水水水

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 -

51nod 1254 最大子段和 V2

N个整数组成的序列a[1],a[2],a[3],…,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数时和为0. 例如:{-2,11,-4,13,-5,-2, 4}将 -4 和 4 交换,{-2,11,4,13,-5,-2, -4},最大子段和为11 + 4 + 13 = 28. 收起 输入 第1行:整数序列的长度N(2 <= N <= 50000) 第2 - N + 1行:N个整数(-10^9 <

【51NOD-0】1049 最大子段和

[算法]DP [题解]开long long-- #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn=50010; int a[maxn],n; int main() { scanf("%d",&n); long long sum=0,ans=0,x; for(int i=1;i<=n;i++) { scanf

51nod 1275 连续子段的差异

分析: 1.首先是尺取,尺取到每一个区间,区间满足这个条件,最大-最小<=k; 2.对于一个动态区间,怎么维护他的最大值,最小值(的下标):——单调队列: 什么时候删掉头结点呢? 当我找到了当前区间的上限:我需要尺取移动头结点了:此时,单调队列不用怕,只要这个头不影响我的单调队列,我就可以不用管:否则弹掉: 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 50000 + 5; 6 int a

最大字段和

1049 最大子段和 基准时间限制:1 秒 空间限制:131072 KB 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) Outpu

51nod 1065 最小正子段和

题目链接:51nod 1065 最小正子段和 房教说用前缀和做,然后看了别人博客懂了后就感觉,这个真有意思... 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N = 50001; 6 const int inf = 0x3f3f3f3f; 7 pair<long long, int> sum[N]; 8 int

51nod 1050 循环数组最大子段和

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1050 题意: 思路: 情况无非分为两种: ①正常的最大子段和. ②首尾相连的最大子段和,此时中间的那段肯定是最小子段和,用总的sum-最小子段和即可. 最后比较两者大小. 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio>