最大子段和的三种求法

最大子段和——用蛮力算法,分治策略,动态规划算法三种求法(C语言) 给定n个整数的序列A=,求该数列最大子段和问题,通过三种算法蛮力算法,分治策略,动态规划算法的分析进行求解。 阅读详情

这里注意子段是连续的,子序列是不连续的。

(1)暴力求解

//最大子段和 暴力 直接三层循环 暴力所有区间 然后找最大的子段和 
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>

using namespace std;
int a[2000];

int main(){
    ios::sync_with_stdio(false);
    cin.tie();
    int n;
    cin >> n;
    for(int i = 0;i < n; i++)
        cin>>a[i];
    int ans =0;
    for(int i = 0;i < n;i++){
        for(int j =i ; j<n ;j++){
            int sum = 0;
            for(int k = i;k<=j;k++){
                sum +=a[k];
            }
            ans=max(sum,ans);
        }
    }


    cout<< ans <<endl;
    return 0;
}
//最大子段和 暴力优化
//a(i~j)可分解为 a(j)+a(i~j-1) 然后发现可以将刚刚的最里层循环给省掉 从而节省一部分时间
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>

using namespace std;
int a[2000];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie();
    int n;
    cin >> n;
    for(int i = 0; i < n; i++)
        cin>>a[i];
    int ans =0;
    for(int i = 0; i < n; i++)
    {
        int sum = 0;
        for(int j =i ; j<n ; j++)
        {
            sum +=a[j];
            ans=max(sum,ans);
        }
    }
    cout<< ans <<endl;
    return 0;
}

(2)采用分治算法的思想

a[0:n-1]可以分为 a[0:n/2] 和 a[n/2+1:n-1]两端 则a[1:n]的最大子段和有以下三种情况

1.a[0:n-1]的最大子段和 与 a[0:n/2]的最大子段和相同    递归即可求解

2.a[0:n-1]的最大子段和 与 a[n/2+1:n-1]的最大子段和相同    递归即可求解

3.a[0:n-1]的最大子段和 为 sum(ak)    k从i到j  1<=i<=n/2,n/2+1<=j<=n    很明显 a[n/2]和a[n/2+1]在最优子序列里。所以可以在a[0:n/2]中计算出 sl=max (sum(ak))  k从i到n/2 0<=i<=n/2 同理a[n/2+1:n]中计算出 sr=max (sum(ak))  k从n/2+1到n n/2+1<=i<=n-1

//最大子段和 分治写法
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>

using namespace std;
int a[2000];
int f(int l,int r){
    int sum = 0;
    if(l==r)
        sum=max(a[l],0);
    else{
        int mid = (floor)((l+r)/2);
        int lsum = f(l,mid);
        int rsum = f(mid+1,r);
        int sl= 0;
        int tmp = 0;
        for(int i = mid; i >= l; i--){
            tmp += a[i];
            sl=max(sl,tmp);
        }
        tmp = 0;
        int sr = 0;
        for(int i=mid + 1;i <= r; i++){
            tmp += a[i];
            sr=max(sr,tmp);
        }
        sum=max(sl+sr,max(lsum,rsum));
    }
    return sum;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie();
    int n;
    cin >> n;
    for(int i = 0;i < n; i++)
        cin>>a[i];
    int ans = f(0,n-1);
    cout<< ans <<endl;
    return 0;
}

(3)dp解法

拿组样例直接跑出动态转移方程即可 然后每次找最大

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
#define ll long long

const int N=1e5+6;
ll dp[N];

int main(){

    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin>>n;
    memset(dp,0,sizeof(dp));
    ll maxans = -1;
    int a;
    for(int i=0;i<n;i++){
        cin>>a;
        dp[i]=max(dp[i],dp[i-1]+a);
        maxans=max(maxans,dp[i]);
    }
    cout << maxans << endl;
    return 0;
}

 

最大子段和系列(二维子段和、环形数组子段和、最大m段和) 思路 一、最大子段和         F(i) =   a[i]      f 阅读详情

相关推荐

避坑指南:CoppeliaSim逆运动学仿真常见报错解决方案(附UR5+RG2爪完整Lua脚本)

本文针对CoppeliaSim机器人仿真中常见的逆运动学报错问题,提供了详细的避坑指南和解决方案。文章以UR5机械臂与RG2夹爪组合为例,深入剖析了模型装配、Dummy节点配置、Lua脚本编写等关键步骤中的常见错误,并附带了完整的、带错误处理的脚本代码,帮助用户快速定位并解决IK仿真失败问题,提升仿真效率。

weixin_29054399的博客 267

最大子段和问题(3种方法)

给定由n个整数(可能为负整数)组成的序列a1,a2, a3… , an, 寻找它的某个连续子段,使得其和最大。例如( -2,11,-4,13,-5,-2 )最大子段是{ 11,-4,13 }其和为20。 1、最大字段和问题的简单算法 (1)枚举法求解: 以a[0]开始: {a[0]}, {a[0],a[1]},{a[0],a[1],a[2]}……{a[0],a[1],……a[n]}共n个 以a[1]开始: {a[1]}, {a[1],a[2]},{a[1],a[2],a[3]}……{a[1],a[2],……

weixin_44469806的博客 5万+

5分钟搞定微服务架构图:手把手教你用Draw.io画出专业级设计

本文详细介绍了如何使用Draw.io快速绘制专业级微服务架构图。通过5分钟入门教程,掌握核心组件拖拽、连接线优化等技巧,提升系统设计可视化效率。特别适合需要快速呈现分布式系统架构的开发团队,利用内置微服务元素和分层展示功能,轻松创建清晰易懂的技术文档。

pz890123的博客 1238

最大子段和详解(N种解法汇总)

问题的提出:给定有n个整数(可能为负整数)组成的序列a1,a2,...,an,求该序列连续的子段和的最大值。如果该序列的所有元素都是负整数时定义其最大子段和为0。例如,当(a1,a2,a3,a4,a5)=(-5,11,-4,13,-4-2)时,最大子段和为11+(-4)+13=20。 解法一:穷举法,即把所有可能情况一一列举穷举法是最直接的想法,把所有的情况列出来,再进行挑选。

钟晓时 2万+

类银河恶魔城学习记录1-1 Player状态机的搭建 P28

什么是状态机?一篇文章就够了 - 知乎说实话,目前并不能深入理解状态机的奇妙之处(当然,我觉得状态机作为教程的重要组成部分是不得不理解的,所以以下我会对游戏教程内的状态机做一些我认为的解释,如有错误,请多包涵)

Homura_的博客 2338

ardupilot开发 --- MavLink 篇

ardupilot开发 --- MavLink 篇

记录老板的每次pua,分享领导每天的毒鸡汤... 4249

动态规划算法(2)--最大子段和与最长公共子序列

最大子段和的暴力枚举、分治法、动态规划法的思路,最长公共子序列暴力检索、动态规划法的思路。

NPU 研0 5605

21、博弈中的对抗搜索算法解析

本文深入解析了博弈中的对抗搜索算法,涵盖极小极大算法、阿尔法-贝塔剪枝、移动排序与换位表等核心技术。文章分析了算法的数学基础与实现机制,探讨了其在国际象棋、围棋等复杂游戏中的应用,并扩展至多人游戏中的联盟与合作行为。通过对比不同类型策略的优劣,展示了对抗搜索在实际博弈系统中的演进方向与优化路径,为人工智能决策提供了理论支持与实践指导。

rust6ferris的博客 128

最大子段和(动态规划详细解析)

给出一个长度为n的序列a,选出其中连续且非空的一段使得这段和最大。

暴力扬 5223

cdk&java | 绘制含有丰富信息的化学反应(适合论文、网页、PPT)

package org.example; import org.openscience.cdk.DefaultChemObjectBuilder; import org.openscience.cdk.depict.DepictionGenerator; import org.openscience.cdk.exception.CDKException; import org.openscience.cdk.interfaces.IReaction; import org.openscience.cdk.

ASKCOS博客 897

BMP390L数字大气压传感器原理图设计,已量产(压力传感器)

在工业设备的室内定位、地下设施监测这类 GPS 信号盲区场景里,气压高度检测的 “靠谱程度” 直接决定了系统的可用性 —— 毕竟谁也不想在地下停车场导航时,设备把 1 楼误判成 3 楼。最近在项目里基于博世 BMP390L 做了硬件电路设计,正好聊聊这款工业级数字气压传感器的硬实力,以及原理图里的那些关键设计细节。

不脱发的程序猿 350

最大子段和四种求法

给定n(1负数时定义子段和为0,依此定义,所求的最优值为: Max{0,a[i]+a[i+1]+…+a[j]},1<=i<=j<=n。 例如,当(a[1],a[2],a[3],a[4],a[5],a[6])=(-2,11,-4,13,-5,-2)时,最大子段和为20. 第一种 暴力求解

且视他人之疑目如盏盏鬼火 1万+

CPU 访问外设的两种核心机制:MMIO(Memory-Mapped I/O) 和 DMA(Direct Memory Access)

BAR和DMA是计算机系统中两种关键的数据传输机制:BAR(基址寄存器)用于CPU与设备间的控制通信,映射设备寄存器便于配置操作;而DMA(直接内存访问)允许设备直接读写系统内存,无需CPU参与大量数据传输。典型场景如NVMe SSD读取数据时,CPU通过BAR下发指令,设备通过DMA高效传输数据到主机内存,最后中断通知CPU。虽然BAR能映射大内存空间,但仍无法替代DMA的高效数据传输功能,两者各司其职——BAR负责控制,DMA专注数据传输,共同实现高性能的硬件交互。

MHD0815的博客 237

最大子段和三种算法实现

问题描述 给定由 n 个整数(可能为负整数)组成的序列 a1、a2、……an,求该序列形如 的子段和的最大值。当所有整数均为负整数时定义其最大子段和为 0。依次定义,所求的最优值为 max{ 例如:当(a1,a2,a3,a4,a5,a6)=(-2,11,-4,13,-5,-2)时,最大子段和为 =20。 三种算法求解 1、暴力算法 算法分析: 通过阅读了解问题后,可以初步尝试用最简单的方法解决问题,方便发现问题本质。最大子段和的结果很明显是通过:对数组排列组合得出子段和的个数,然后一一对比得出结果。 求子

weixin_46274553的博客 6307

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

P1115 最大子段和

刷题:P1115 最大子段和。

AllenAC的博客 1227

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

最大连续子段和

定义一个变量maxn初始化为无穷小,更新最大子段和,同时定义一个变量res初始化为0,表示当前子段的和.我们考虑x数组的第i个元素xi,如果当前子段和加上xi是一个大于等于0的数,那么当前的子段和一定对后面的元素有贡献,所以将xi加到res里,同时更新最大子段和maxn;反之,如果当前子段和res加上xi是一个负数,那么,加上后的子段和一定对后面的元素有副作用,此时抛弃当前子段和res,从xi1重新开始上述操作。−3−1−2由于resxi。

qq_73702550的博客 866

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

最小子段和,最大子段和,最小正子段和

最大子段和比较好求解,就是一个dp标记走就可以了,当dp 最小子段和就是把所有的元素去相反数,然后在此基础上求一个最大子段和就好。 主要想说的是最小正子段和的求法,是先算前i位的累加和dp[i],并记录标记为i。 然后对所有的dp[i]进行小到大的排序,然后对两个相连的dp[i],如果后者的标记大于前者的标记,那么它们的差值是候选答案,然后选取候选答案最小的那个。 PS:注

kevin_liu11的专栏 2589

最大子段和问题

不过,由于题目要求我们必须选择非空的子序列,那么我们就要考虑数组全都死负数的特殊情况了,此时,不存在非空连续区间和不为负数的情况,那么我们最后一个数都不选,得到的结果为 0。因此,我们可以使用递推的形式,贪心的选择每一个数,如果加上当前数之后和小于 0,那么当前数肯定小于 0,并且,这一段连续子序列我们都不选。头稍微不好处理,因为题目要求要求最大连续子段和不能小于 0,所以当前元素小于 0 时,我们不能选它。的初始化也要注意,求最大值要初始化为最小值,因为最大值可能为负数,所以不能用 0 作为最小值。

jyyyyx的算法之旅 992

最大子段和问题,最大子矩阵和问题,最大m子段和问题

1、最大子段和问题 问题定义:对于给定序列a1,a2,a3……an,寻找它的某个连续子段,使得其和最大。如( -2,11,-4,13,-5,-2 )最大子段是{ 11,-4,13 }其和为20。 (1)枚举法求解 枚举法思路如下: 以a[0]开始: {a[0]}, {a[0],a[1]},{a[0],a[1],a[2]}……{a[0],a[1],……a[n]}共n个 以a[1]开始:

~~~~~~常思~~~~~ 1368

最大子段和

问题 A: 最大子段和 时间限制: 1 Sec 内存限制: 128 MB [提交] [状态] 题目描述 Geobiyye是一个喜欢思考问题的女孩子。 Geobiyye给了你一个序列,她想求出这个序列的最大子段和。 Geobiyye觉得这个问题太简单了,她将问题扩大了一倍。于是现在问题变成了:从这个序列中选出不相交的两个连续段,要求它们的和最大。 换句话说,对于给定的长度为n的序列ai,你需要给出...

林苏泽 683

最大子段和与最大M子段和模板

最大子段和: int Sum(int* a, int n)/*a为序列,n为序列长度*/ { int curSum = 0; int maxSum = 0; for (int i = 0; i < n; i++) { if (curSum + a[i] < 0) curSum = 0; else

Tyshawn的博客 994

最大子段和问题(这里给出三种算法)

问题描述对于给定序列a1,a2,a3……an,寻找它的某个连续子段,使得其和最大。如( -2,11,-4,13,-5,-2 )最大子段是{ 11,-4,13 }其和为20。     (1)枚举法求解     枚举法思路如下:     以a[0]开始: {a[0]}, {a[0],a[1]},{a[0],a[1],a[2]}……{a[0],a[1],……a[n]}共n个     以a[1]开始: {

qq_38010909的博客 1048

HAUTOJ奇数最大子段和

题目描述 一个大小为n的数组a1到an(−10^4≤ai≤10^4)。请你找出一个连续子段,使子段长度为奇数,且子段和最大。 输入 第一行为T(1≤T≤5),代表数据组数。 之后每组数据,第一行为n(1≤n≤10^5),代表数组长度。 之后一行n个数,代表a1到an。 输出 每组数据输出一行,表示满足要求的子段和最大值 样例输入 141 2 3 4 样例输

Tanglouis2017的博客 1160

最大子段和,最大子段积

#include using namespace std;//最大子段和 double MaxSubSum(double *p,const int n); double MaxSubMutil(double *p,const int n); int main() {  double p[]={1,-2,-3,4,-5,6,-7};  cout<<MaxSubMutil(p,7)<<

fdcumt的专栏 1188
上一篇: 磁盘调度算法
下一篇: 会场安排问题
Puppet__
博客等级 码龄10年 319粉丝 328原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值