官方题解 | #子数组最大连续和#

子数组最大连续和

http://www.nowcoder.com/practice/1718131e719746e9a56fb29c40cc8f95

子数组最大连续和

难度:2星

解法1 动态规划

定义 dp[i]dp[i] 为前 ii 个数中,以第 ii 个数结尾的子数组最大连续和。

于是有转移方程:

dp[i]=max(dp[i1]+a[i],a[i])dp[i]=max(dp[i-1]+a[i],a[i])

其中,前面部分代表选择前面的区间的最大值,后面部分代表直接选择a[i]。

最终答案是所有的 dp[i]dp[i] 的最大值。


#include<bits/stdc++.h>
using namespace std;
long long a[101010],dp[101010];
int main(){
    int n,i;
    cin>>n;
    for(i=1;i<=n;i++)cin>>a[i];
    dp[0]=-1e9;
    long long res=-1e9;
    for(i=1;i<=n;i++){
        dp[i]=max(dp[i-1]+a[i],a[i]);
        res=max(res,dp[i]);
    }
    cout<<res;
    
}

解法2 贪心

我们用一个变量维护到当前位置的最大和,当加到负数的时候我们就可以把它置为0,因为显然负数再往后加会让答案变小。最终维护这个变量的最大值即可。

这种做法需要特判所有数均为负数的情况。这种情况直接输出绝对值最小的那个负数就行了。

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
ll dp[101010];
ll a[101010];
int main(){
    int n,i;
    cin>>n;
    int jud=0;
    for(i=1;i<=n;i++){cin>>a[i];if(a[i]>=0)jud=1;}
    if(!jud){
        ll res=-1e9;
        for(i=1;i<=n;i++)res=max(res,a[i]);
        cout<<res;
        return 0;
    }
    ll res=a[1],sum=max(0LL,a[1]);
    for(i=2;i<=n;i++){
        sum=max(0LL,sum+a[i]);
        res=max(res,sum);
    }
    cout<<res;
}
全部评论
官方题解的数组大小已经跟题面对应不上了 捂脸
点赞 回复 分享
发布于 2025-04-01 10:27 浙江
动态规划dp[2]不应该是1吗为什么是-1呀
点赞 回复 分享
发布于 2023-03-07 13:58 湖北
贪心解法不太对吧
点赞 回复 分享
发布于 2022-11-26 11:34 陕西
动态规划的解法思路很好,但是申明两个大内存数组是没必要的a可以用new long long[n]动态分配,dp其实直接定义成long long就可以了
点赞 回复 分享
发布于 2021-12-23 14:02

相关推荐

01-14 16:23
广州商学院 Java
双非后端失败第N人:如果准备好了可以直接投字节,字节是最不看学历的,只要想面,大概率都能给你约面。
双非有机会进大厂吗
点赞 评论 收藏
分享
牛客66512506...:那个百度acg是不是个小哥啊,老是问些底层问题狠狠为难,然后kpi
哪些公司在招寒假实习?
点赞 评论 收藏
分享
评论
11
3
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务