最大子段和之分治递归法

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

Time Limit: 10 ms Memory Limit: 400 KiB

Submit Statistic

Problem Description

给定n(1<=n<=50000)个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时定义子段和为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。

**注意:**本题目要求用分治递归法求解,除了需要输出最大子段和的值之外,还需要输出求得该结果所需的递归调用总次数。

递归调用总次数的获得,可以参考以下求菲波那切数列的代码段中全局变量count的用法:

#include
int count=0;
int main()
{
    int n,m;
    int fib(int n);
    scanf("%d",&n);
    m=fib(n);
    printf("%d %d\n",m,count);
    return 0;
}
int fib(int n)
{
    int s;
    count++;
    if((n==1)||(n==0)) return 1;
    else s=fib(n-1)+fib(n-2);
    return s;
}
Input

第一行输入整数n(1<=n<=50000),表示整数序列中的数据元素个数;

第二行依次输入n个整数,对应顺序表中存放的每个数据元素值。

Output

一行输出两个整数,之间以空格间隔输出:

第一个整数为所求的最大子段和;

第二个整数为用分治递归法求解最大子段和时,递归函数被调用的总次数。

Sample Input
6
-2 11 -4 13 -5 -2
Sample Output
20 11

首先,假定有区间[l…r][l…r],其中间位置为midmid,其最大子段为[i…j][i…j]。那么显然,ii和jj必定符合下列三种情况之一:
1.l \leq{i} \leq{j} \leq{mid}l≤i≤j≤mid2.i \leq{mid} <j \leq{r}i≤mid<j≤r3.mid < i \leq{j} \leq{r}mid<i≤j≤r
只需要分别求出三种情况下的值,取其最大的即可。

其中,很容易求出第二种情况,即求出区间[i…mid][i…mid]与区间[mid+1…j][mid+1…j],将其相加即可。复杂度O(n)O(n)
如何处理第一种和第三种情况呢?也不难发现,第一种情况,其实就是求区间[1…mid][1…mid]中的最大值,第三种情况就是求区间[mid+1…r][mid+1…r]中的最大值。那么,只需递归求出即可。

显然,该解法的复杂度为 O(nlogn),O(nlogn) 通过此题是没问题的。

#include<bits/stdc++.h>
using namespace std;
int n,arr[200200];//开数组存数字
int c= 0;//递归次数
int rec(int l,int r){
    int sum = 0;
    c++;
    //当左右相等时
    if(l==r){
        if(arr[l]>=0)
            sum = arr[l];
        else
            sum = 0;
    }
    else
    {
        int  mid = (l+r)>>1;
        int leftsum = rec(l,mid);
        int rightsum = rec(mid+1,r);

        int s1,s2,ss;

        s1 = ss =0;
        for(int i=mid;i>=l;--i){
            ss+=arr[i];
            s1 = max(ss,s1);
        }

        s2 = ss =0;
        for ( int i=mid+1;i<=r;++i){
            ss+=arr[i];
            s2 = max(ss,s2);
        }

        sum = max(max(s1+s2,leftsum),rightsum);
    }
    return sum;
}

int main(){
    scanf("%d",&n);
    for(int i = 0; i<n; ++i)
		scanf("%d", &arr[i]);
    cout<<rec(0,n-1)<<" "<<c<<endl;
    return 0;
}

顺序表应用7:最大子段和之分治递归法 顺序表应用7:最大子段和之分治递归法 Time Limit: 10 ms Memory Limit: 400 KiB Problem Description 给定n(1<=n<=50000)个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时定义子段和为0,依此定义,所求的最优值... 阅读详情

相关推荐

C - 顺序表应用7:最大子段和之分治递归法

C - 顺序表应用7:最大子段和之分治递归法 Description 给定n(1<=n<=50000)个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时定义子段和为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,1.

°渐行渐远っ的博客 1801

顺序表应用7:最大子段和之分治递归法【分治算法】

顺序表应用7:最大子段和之分治递归法【分治算法】

m0_46308522的博客 2496

算法-基于MACD的Adaboost股价涨跌预测模型

MACD是一个指标,具体用法是MACD>0看涨,反之看跌,果真是这样的吗?由于所有的技术指标都基于对历史数据的统计,指标的滞后性也就难免,有时候MACD明明大于0,股价仍然跌,有时候macd小于0,股价仍然涨。 本文基于Adaboost算法提出了一种基于macd的线性阀值分类器作为若分类器,通过在限定的解空间内寻找使得错误率最小的阀值和偏置,这样做避免了训练若分类器的复杂性,经验证,这种方法有效。

mtaxot的博客 8023

【最大子数组和】问题具体思路——【循环暴搜】【贪心】【动态规划】【分治】(附完整代码)

本文将围绕【最大子数组和】问题展开讨论。对于这一问题将采用多种思路方法来解决【循环暴搜】【贪心】【动态规划】【分治】

bufangbufang的博客 1759

死区补偿---学习笔记

最近调试中发现,死区补偿对电流谐波和电流带宽影响挺大,于是对死区补偿产生浓厚兴趣,找来几篇文章粗读并做一下笔记。 传统做法 无非就是根据电流方向补偿,假如svpwm计算出的A相理论导通实践为T1,死区时间是Td,则实际导通时间T = T1-Td(when ia >0 ),于是在svpwm计算出的导通时间T1的基础上加上Td。这样经过PWM模块后,实际的导通时间即为T1. 但存在两个难点(个人总结): 1,受电流检测精度影响,尤其是在过零点检测困难。 2,真实的二极管导通需要一定电压,并非..

圆桌骑士的博客 2万+

Orcad原理图导入Allegro

在即将设计的PCB中,将层叠设置好后,执行File→import→parameters,将刚才导出的.prm文件导入,很多参数就自动设置好了,与已完成的PCB里的参数保持一致。具体操作是:在已完成的PCB里执行File→Exoprt→Parameters,弹出下图所示的对话框,选择需要导出的设计参数后,设置到导出路径,导出记录设计参数的文件(.prm)。在.brd文件导入网表后,往往需要页面大小、格点、各层叠里各要素显示颜色等参数,手动设置十分麻烦,我们可以在一块已经完成的PCB里导出记录设计参数的文件。

sinat_27007097的博客 2085

求最大字段和(穷举法、动态规划、分治法)

分别使用穷举法、动态规划、分治法来求最大子段和

weixin_49588575的博客 1539

LeRobot 入门教程(九)使用 Android、iOS 手机控制机械臂

本指南详细介绍了如何使用iOS/Android手机远程控制机器人。内容包括:1)安装依赖(pip install leroobot[phone]);2)平台支持说明(iOS需HEBI Mobile I/O应用/Android用WebXR);3)手机方向校准方法;4)控制模式设定(按钮/手势);5)示例脚本使用(遥操作/数据记录/回放/策略评估);6)关键参数配置(运动学/安全限制/夹爪控制);7)故障排查方法。支持ROS2集成,提供URDF文件处理、逆向运动学计算和实时可视化功能,适用于物理机器人和仿真环境

2506_90492529的博客 1658

最大子段和的分治算法

问题描述 给定由 n 个整数(可能为负整数)组成的序列,求解其连续的最大字段和。当所有数都是负整数时,最大字段和是 0 . 如:a[] = {-2, 11, -4, 13, -5, -2}时, max = 11 + (-4) + 13 = 20. 分治算法思想 将所给序列a[1:n] 分成a[1:n/2] 和 a[n/2 + 1 : n]两个部分,则最大值有一下三种情况: 整个序列的字段和与左半部分相同 整个序列的子段和与右半部分相同 整个序列的子段和 在两个部分的中间连接部分 对应前两种情况利用递归可

果果冻冻的博客 4394

【STK】手把手教你利用STK进行导弹和反导仿真02 - STK/MMT模块01 导弹任务分析工具概述

种工具:导弹设计工具(Missile Design Tool,MDT )、导弹飞行工具(Missile Flight Tool,截弹,或者用内置拦截弹编辑器创建的个性化的拦截弹, IFT 能够对 ―一对一 ‖动能拦截。导设置系统参数, 并对其有效性进行验证, 画性能图,保证该设计是可行的。(SAIC)公司联合开发研制,极大扩展了 STK 原有的导弹对象的功能,能够精确仿真。IFT 能够对拦截飞机、 导弹、卫星等目标进行仿真和分析。(2)推进系统参数,包括推力,比冲,秒流量,推力持续时间,喷嘴出口面积,

weixin_44184852的博客 1877

RK3588 平台部署实战:OpenCV + LibTorch + FFmpeg 环境搭建与深度学习推理全流程解析

现在,你已经掌握了在RK3588上搭建OpenCV+LibTorch+FFmpeg环境的完整流程,也完成了深度学习模型的部署测试。不妨从一个具体的应用场景入手(如检测自家宠物的品种),亲手打造属于你的第一个边缘智能应用——当你看到模型在RK3588上精准输出结果时,你会发现:嵌入式深度学习的门槛,其实并没有想象中那么高。这些依赖是编译OpenCV、FFmpeg的基础,安装过程中若提示权限不足,可在命令前加。若能输出预测的类别索引,则说明环境搭建成功,模型推理流程通畅。文件,实现模型加载、图像预处理与推理。

FJN110的博客 535

3664 最大子段和之分治递归法

顺序表应用7:最大子段和之分治递归法 Time Limit:10 msMemory Limit:400 KiB Problem Description 给定n(1<=n<=50000)个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时定义子段和为0,依此定义,所求...

动感超人_Crush 214

机器人中的数值优化(十三)——QP二次规划

本系列文章主要是我在学习《数值优化》过程中的一些笔记和相关思考,主要的学习资料是深蓝学院的课程《机器人中的数值优化》和高立编著的《数值最优化方法》等,本系列文章篇数较多,不定期更新,上半部分介绍无约束优化,下半部分介绍带约束的优化,中间会穿插一些路径规划方面的应用实例

慕羽★的博客 2793
上一篇: 骨牌铺方格
下一篇: 最少硬币问题
ArtinCode
博客等级 码龄9年 23粉丝 49原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值