100题_03 最大子序列和

题目:

输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。要求时间复杂度为O(n)。例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,因此输出为该子数组的和18。

 

 

请参考:

http://www.cnblogs.com/youwang/archive/2010/07/16/1778929.html

 

问题扩展:

 

给定一个序列1,2,3,4,5,6,7,8 ,在首尾相连的情况下求S的一段连续序列,使得序列和的绝对值最大.输出这个最大值。

 

 

http://tianwei.dlut.edu.cn:8000/problem/show/1310

 

可以分两种情况进行考虑,第一种是不越过1和8的情况(同上面的问题),另外一种是越过1和8的情况。对于第二种情况,可以让总和减去除1和8外的最小子序列和。

 

代码:

#include <cstdio>
#include 
<cmath>

using namespace std;

int su;
int s[100000];
int f[100000];

int max_seq(int a[], int n)
{
    
int i;
    f[
0= a[0];
    
int max = a[0];
    
for (i = 1; i < n; i++)
    {
        f[i] 
= f[i-1> 0 ? f[i-1+ a[i] : a[i];
        
if (f[i] > max)
        {
            max 
= f[i];
        }
    }
    
return max;
}

int min_seq(int a[], int n)
{
    
int i;
    f[
0= a[0];
    
int min = a[0];
    
for (i = 1; i < n; i++)
    {
        f[i] 
= f[i-1< 0 ? f[i-1+ a[i] : a[i];
        
if (f[i] < min)
        {
            min 
= f[i];
        }
    }
    
return min;
}

int sum(int a[], int n)
{
    
int s = 0;
    
for (int i = 0; i <n; i++)
    {
        s 
+= a[i];
    }
    
return s;
}


int max_seq_over(int a[], int n)
{
    
return su - min_seq(&a[1], n - 2);
}

int min_seq_over(int a[], int n)
{
    
return su - max_seq(&a[1], n - 2);
}

int max_seq_loop_abs(int a[], int n)
{
    
if (n == 1)
    {
        
return abs(a[0]);
    }
    
if (n == 2)
    {
        
int e = abs(a[0]);
        
int f = abs(a[1]);
        
int g = abs(a[0+ a[1]);
        
if (f > e )
        {
            e 
= f;
        }
        
if (g > e)
        {
            e 
= g;
        }
        
return e;
    }
    su 
= sum(a, n);
    
int max = max_seq(a, n);
    
int tmp = abs(min_seq(a, n));
    
if (tmp > max)
    {
        max 
= tmp;
    }
    tmp 
= max_seq_over(a, n);
    
if (tmp > max)
    {
        max 
= tmp;
    }
    tmp 
= abs(min_seq_over(a, n));
    
if (tmp > max)
    {
        max 
= tmp;
    }
    
return max;
}

int main()
{
    
int n, i;
    
while (scanf("%d"&n) != EOF)
    {
        
for (i = 0; i < n; i ++)
        {
            scanf(
"%d"&s[i]);
        }
        printf(
"%d ", max_seq_loop_abs(s, n));
        delete[] s;
    }
    
return 0;
}

 

 

 

posted on 2011-03-02 11:15  小橋流水  阅读(183)  评论(0编辑  收藏  举报

导航