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

子数组最大连续和

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;
}
全部评论
官方题解的数组大小已经跟题面对应不上了 捂脸
点赞 回复 分享
发布于 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

相关推荐

Southyeung:我说一下我的看法(有冒犯实属抱歉):(1)简历不太美观,给我一种看都不想看的感觉,感觉字体还是排版问题;(2)numpy就一个基础包,机器学习算法是什么鬼?我感觉你把svm那些写上去都要好一点。(2)课程不要写,没人看,换成获奖经历;(3)项目太少了,至少2-3个,是在不行把网上学习的也写上去。
点赞 评论 收藏
分享
04-27 08:59
常州大学 Java
牛客139242382号:《两门以上汇编语言》
点赞 评论 收藏
分享
评论
11
2
分享

创作者周榜

更多
牛客网
牛客企业服务