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   小橋流水  阅读(184)  评论(0编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述

导航

统计

点击右上角即可分享
微信分享提示