算法笔记--最大子段和问题

1.非连续最大子段和

如果不全为负数,最大子段和所有大于等于0的元素的和;如果全为负数,最大子段和为最大的负数。

2.连续最大子段和

①无长度限制:

例题:

洛谷p1115最大子段和

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=2e5+5;
int a[N];
int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n;i++)cin>>a[i];
    int temp=0;
    int ans=0;
    int maxn=-INF;
    bool flag=true;
    for(int i=0;i<n;i++)
    {
        temp+=a[i];
        maxn=max(maxn,a[i]);
        if(a[i]>=0)flag=false;
        if(temp<0)
        {
            temp=0;
        }
        ans=max(ans,temp);
    }
    if(flag)cout<<maxn<<endl;
    else cout<<ans<<endl;
    return 0;
}

安利一下我们学校的oj

zstuoj1361最大利益

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
const int INF=0x3f3f3f3f;
int sum[N];
int a,maxsum,minsum;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin>>t;
    int l,r;
    int ansl,ansr,ans;
    for(int i=1;i<=t;i++)
    {
        memset(sum,0,sizeof(sum));
        maxsum=-INF;
        minsum=0;
        ans=-INF;
        int ma=-INF;
        l=0;
        int ll=0;
        bool flag=false;
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            int a;
            cin>>a;
            if(a>ma)
            {
                ma=a;
                ll=i;
            }
            if(a>=0)flag=true;
            sum[i]=sum[i-1]+a;
            if(sum[i]>maxsum)
            {
                maxsum=sum[i];
                r=i;
            }
            if(sum[i]<minsum)
            {
                minsum=sum[i];
                l=i;
            }
            if(sum[r]-sum[l]>ans&&r>l)
            {
                ans=sum[r]-sum[l];
                ansl=l+1;
                ansr=r;
            }
        }
        cout<<"Payoff "<<i<<":"<<endl;
        if(flag)cout<<ans<<‘ ‘<<ansl<<‘ ‘<<ansr<<endl;
        else cout<<ma<<‘ ‘<<ll<<‘ ‘<<ll<<endl;
        cout<<endl;
    }
    return 0;
}

②有长度限制(如最大连续奇数字段和)

杭电集训队排位赛

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int a[N];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        for(int i=0;i<n;i++)cin>>a[i];
        int sum=a[0],ans=a[0];
        for(int i=1;i<n-1;i+=2)
        {
            sum+=a[i]+a[i+1];
            if(sum<a[i+1])sum=a[i+1];
            ans=max(ans,sum);
        }
        sum=a[1];
        for(int i=2;i<n-1;i+=2)
        {
            sum+=a[i]+a[i+1];
            if(sum<a[i+1])sum=a[i+1];
            ans=max(ans,sum);
        }
        cout<<ans<<endl;
    }
    return 0;
}

时间: 2024-09-30 18:17:22

算法笔记--最大子段和问题的相关文章

算法笔记-DTW动态时间规整

算法笔记-DTW动态时间规整 简介 简单的例子 定义 讨论 约束条件 步模式 标准化 点与点的距离函数 具体应用场景 分类 点到点匹配 算法笔记-DTW动态时间规整 动态时间规整/规划(Dynamic Time Warping, DTW)是一个比较老的算法,大概在1970年左右被提出来,最早用于处理语音方面识别分类的问题. 1.简介 简单来说,给定两个离散的序列(实际上不一定要与时间有关),DTW能够衡量这两个序列的相似程度,或者说两个序列的距离.同时DTW能够对两个序列的延展或者压缩能够有一定

小算法笔记

素数: 除 1 外只能被 1 和自身整除的数. 方法一: #include <stdio.h> #define N 1000 int num = 0; int prime(int n) { int i; if(n % 2 == 0) return (n == 2); if(n % 3 == 0) return (n == 3); if(n % 5 == 0) return (n == 5); for(i = 7; i*i <= n; ++i) if(n % i == 0) return

算法笔记之堆排序

一.对堆排序的相关了解 1.堆排序的运行时间是 O(nlogn) : 2.定义: 堆heap是一棵具有以下属性的二叉树-- (1)它是一棵完全二叉树: (2)每个结点大于或等于它的任意一个孩子. 备注:完全二叉树的定义--除了最后一层没填满以及最后一层的叶子都是偏左放置的,其他层都是满的二叉树! 3.二叉堆有两种:最大堆和最小堆.在堆排序中我们使用的是最大堆,最小堆常常在构造优先队列时使用. 4.一条路径的深度指的是这条路径的边数,一个结点的深度是指从根结点到该结点的路径的长度. 二.对堆进行排

算法笔记_023:拓扑排序(Java)

目录 1 问题描述 2 解决方案 2.1 基于减治法实现 2.2 基于深度优先查找实现 1 问题描述 给定一个有向图,求取此图的拓扑排序序列. 那么,何为拓扑排序? 定义:将有向图中的顶点以线性方式进行排序.即对于任何连接自顶点u到顶点v的有向边uv,在最后的排序结果中,顶点u总是在顶点v的前面. 2 解决方案 2.1 基于减治法实现 实现原理:不断地做这样一件事,在余下的有向图中求取一个源(source)(PS:定义入度为0的顶点为有向图的源),它是一个没有输入边的顶点,然后把它和所有从它出发

算法笔记_018:旅行商问题(Java)

目录 1 问题描述 2 解决方案 2.1 蛮力法   1 问题描述 何为旅行商问题?按照非专业的说法,这个问题要求找出一条n个给定的城市间的最短路径,使我们在回到触发的城市之前,对每个城市都只访问一次.这样该问题就可以表述为求一个图的最短哈密顿回路的问题.(哈密顿回路:定义为一个对图的每个顶点都只穿越一次的回路) 很容易看出来,哈密顿回路也可以定义为n+1个相邻顶点v1,v2,v3,...,vn,v1的一个序列.其中,序列的第一个顶点和最后一个顶点是相同的,而其它n-1个顶点都是互不相同的.并且

算法笔记1-最大子序列和问题的求解

问题-- 给定N个整数(有可能是负数)A1,A2,A3,A4...An,求最大子序列和. (子序列必须是连续的):比如,对于输入,-2,11,-4,13,-5,-2:这个序列, 答案是20,即从A2到A4. 对于这个问题,你怎么想的呢?下面有四种解法,看看你的解法是不是其中之一. 解法一.穷举 解题思路-- 既然是求某一个连续的子序列的最大和,那么我们把所有的子序列的和都加一遍,然后用一个变量来存储最大的和值,当遍历一遍所有子序列,即可得到最大的和.由于这个子序列长度可以是1,也可以是N,因此需

[数据结构和算法]折半插入排序算法笔记

/// <summary> /// 步骤: /// 1.记录当前待排元素 /// 2.标记顺序表有序查找区域下界和上界 /// 3.在顺序表有序查找区域中折半查找等待排序元素的位置 /// 4.把顺序表有序查找区域的某些元素后移一位,以空出位置给等待排序的元素 /// 5.在空出的位置填写当前排序元素 /// </summary> /// <param name="elements"></param> static void SqList

算法笔记2-优先队列(堆)(上)

一.什么是优先队列? 看一情景:我们去KTV唱歌,点歌的时候,可以发现所点的歌就是一个队列. 这时候,一个MM突然不玩手机了想唱歌,于是她来点歌,并且想尽早轮到她. 于是她可以选择"插歌"这个功能插到前排队列里. 这种具备可以插入优先权元素的队列,就叫优先队列.但是,这个定义不是严谨的. 优先队列的基本模型是这样的-- 具备两个功能: insert插入: deleteMin 删除最小者. 它的工作就是-- 它很有用哦,具体可以用在操作系统,外部排序和贪婪算法中等. 二.怎么实现优先队列

算法笔记_071:SPFA算法简单介绍(Java)

目录 1 问题描述 2 解决方案 2.1 具体编码   1 问题描述 何为spfa(Shortest Path Faster Algorithm)算法? spfa算法功能:给定一个加权连通图,选取一个顶点,称为起点,求取起点到其它所有顶点之间的最短距离,其显著特点是可以求含负权图的单源最短路径,且效率较高.(PS:引用自百度百科:spfa是求单源最短路径的一种算法,它还有一个重要的功能是判负环(在差分约束系统中会得以体现),在Bellman-ford算法的基础上加上一个队列优化,减少了冗余的松弛