P1115 最大子段和

第一篇博客,背景:为了五月的省赛叮当猫要求洛谷刷题,我刷的很慢而且不喜欢总结,手写潦草而且慢;想到这里都是大神,以前题解都是来这找的,遂想自己把总结写到这里,话不多说,有什么话以后再说。

 

题目描述

给出一段序列,选出其中连续且非空的一段使得这段和最大。

输入输出格式

输入格式:

输入文件maxsum1.in的第一行是一个正整数N,表示了序列的长度。

第2行包含N个绝对值不大于10000的整数A[i],描述了这段序列。

输出格式:

输入文件maxsum1.out仅包括1个整数,为最大的子段和是多少。子段的最小长度为1。

输入输出样例

输入样例#1:复制

7
2 -4 3 -1 2 -4 3

输出样例#1:复制

4

说明

【样例说明】2 -4 3 -1 2 -4 3

【数据规模与约定】

对于40%的数据,有N ≤ 2000。

对于100%的数据,有N ≤ 200000。

///分割线

#include <bits/stdc++.h>
//最大字段和, 我以前做过用的递归没想到如何O(n), 今天看到大佬代码与以前思路相同, 大佬已经实现
 

int main(){
    int n;
    int N[2000 + 5];
    cin >> n;
    for (int i = 0; i < n; ++i)    cin >> N[i];
    int max = N[0], sum = 0;
    if (max > 0)    sum = max;
    for (int i = 1; i < n; ++i)    {
        sum += N[i];
        if (sum > max)    max = sum;
        if (sum < 0)    sum = 0;
    }
    cout << max << endl;
    return 0;
}


//又看到DP的思想, dp[i]数组用来存当前1~i最大的数
 

int main(){
    int Max = - (1 << 30);
    int n, N[200000 + 5] = {0}, dp[200000 + 5] = {0};
    cin >> n;
    for (int i = 1; i <= n; ++i)    {
        cin >> N[i];
        dp[i] = max(dp[i - 1] + N[i], N[i]);
        Max = max(Max, dp[i]);
    } 
    cout << Max << endl;
    return 0;
}


//再贴上我的源代码, 第二组样例错误
 

int n;
int N[200000 + 5];
int main(){
    cin >> n;
    for (int i = 0; i < n; ++i)        cin >> N[i]; 
    cout << fun(0, n - 1) << endl;
    return 0;
}
int fun(int l, int r){
    if (l == r)    return N[l];
    int min = (l + r) / 2;
    int lmax = fun(l, min);
    int rmax = fun(min + 1, r);
    int max = lmax > rmax ? lmax : rmax;
    int sum = 0, lsum = 0, rsum = 0;
    for (int i = min; i >= l; --i)    {
        sum += N[i];
        if (sum > lsum)    lsum = sum;
    }
    sum = 0;
    for (int i = min + 1; i <= r; ++i)    {
        sum += N[i];
        if (sum > rsum)    rsum = sum;
    }
    sum = lsum + rsum;
    if (sum > max)    return sum;
    return max;
} 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值