luogu P1115 最大子段和

题解

最大子段和是个比较经典的算法题,解法很多。
这里给出一个O(n)的解法,自己想的比较直观:
设max_sum为最大累计和 cur_sum为当前累计和,要想获得最大的连续和,显然要尽可能保持cur_sum为正数,
试想如果为负,那么接下来加上什么数字都是减少的。
对此时处理的位置(不妨设为num[i]),如果cur_sum为正数且cur_sum+num[i] > 0 ,
那么我们更新cur_sum = cur_sum+num[i] ,否则(其他一切情况 包括cur_sum<0) cur_sum=num[i]
然后检查此时cur_sum 是否大于max_sum来更新即可。

ps: 为什么这个思路是正确的? 因为正数累计下去有可能增大,而负数绝无可能。

pss: 最后给出一个比较正统的dp方法(其实跟我的一样,但是更凝练)
f[i] = max( f[i-1]+num[i], num[i] )


代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;

int n,m,ans=0;
int main(){

    cin >> n;
    int c_sum,m_sum,tmp;
    cin>>c_sum;
    m_sum = c_sum;// 累计和 初始化为第一位数字

    for(int i=1;i<n;i++){
        cin>>tmp;
        if( c_sum >0 && tmp+c_sum >0) c_sum+=tmp;
        else c_sum = tmp;

        m_sum = m_sum > c_sum ? m_sum : c_sum;
    }

    cout<<m_sum<<endl;

    return 0;
}

猜你喜欢

转载自blog.csdn.net/smmyy022/article/details/81152733