码迷,mamicode.com
首页 > 其他好文 > 详细

poj2479 最大子段和

时间:2018-02-04 22:55:02      阅读:410      评论:0      收藏:0      [点我收藏+]

标签:pac   main   解题思路   namespace   ffffff   std   ret   count   img   

技术分享图片

题意:给定一个数列。求出数列中不相交的两个子段和,要求和最大

解题思路:对每一个i来说,求出[0-i-1]的最大子段和以及[i-n-1]的最大子段和,再加起来,求出最大的一个。[0-i-1]的最大子段和从左到右扫描。[i-n-1]从右到左扫描

#include<cstdio>
#include<algorithm>
using namespace std;

const int MAXN = 50000;
const int INF = 0x3ffffff;

int a[MAXN + 5];
int left[MAXN + 5],right[MAXN + 5];

int main()
{
    int count;
    scanf("%d",&count);
    while(count--)
    {
        int n;
        scanf("%d",&n);
        for(int i = 0;i<n;i++)
            scanf("%d",&a[i]);
        left[0] = a[0];//此时left[i]表示包含i在内左边的最大子段和 
        for(int i = 1;i<n;i++)
        {
            if(left[i-1]<0)
                left[i] = a[i];
            else
                left[i] = a[i] + left[i-1];
        }
        for(int i = 1;i<n;i++)//此时left[i]表示i左边的最大子段和 
            left[i] = max(left[i],left[i-1]);
        right[n-1] = a[n-1];//此时right[i]表示包含i在内右边的最大子段和 
        for(int i = n-2;i>=0;i--)
        {
            if(right[i+1]<0)
                right[i] = a[i];
            else
                right[i] = a[i] + right[i+1];    
        } 
        for(int i = n-2;i>=0;i--)//此时right[i]表示i右边的最大子段和 
            right[i] = max(right[i],right[i+1]);
        int num = -INF;
        for(int i = 1;i<n;i++)//求每一个i左边和右边的最大子段和相加,取最大值。 
            num = max(num,left[i-1]+right[i]);
        printf("%d",num);
    }
    return 0;
}
 

 

poj2479 最大子段和

标签:pac   main   解题思路   namespace   ffffff   std   ret   count   img   

原文地址:https://www.cnblogs.com/ZZUGPY/p/8414361.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!