求解最大子段和问题

求解最大子段和问题。

对于给定序列a1,a2,a3……an,寻找它的某个连续子段,使得其和最大。如( -2,11,-4,13,-5,-2 )最大子段是{ 11,-4,13 }其和为20。

要求:分别用教材所给的三种方法求解(简单方法、分治法、动态规划),通过实例比较结果和时间效率。

提交内容:算法的思想、程序源代码及其说明、实例运行结果及分

简单方法求解:

以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],……a[n]}共n-1个

……

以a[n]开始:{a[n]}共1个

暴力破解方法简单直观,通过两层嵌套循环遍历所有可能的子段,计算它们的和,并保留最大和。这种方法的时间复杂度为O(n^2),适用于小规模数据集。

分治方法:

将序列a[1:n]分成长度相等的两段a[1:n/2]和a[n/2+1:n],分别求出这两段的最大字段和,则a[1:n]的最大子段和有三中情形:

a[1:n]的最大子段和与a[1:n/2]的最大子段和相同;

a[1:n]的最大子段和与a[n/2+1:n]的最大子段和相同;

a[1:n]的最大字段和为∑ak,且1<=i<=n/2,n/2+1<=j<=n。

可用递归方法求得情形1、2。对于情形3,可以看出a[n/2]与a[n/2+1]在最优子序列中。因此可以在a[1:n/2]中计算出

,并在a[n/2+1:n]中计算出 。则s1+s2即为出现情形3时的最优值。

        

        分治法采用递归的方式将问题划分成更小的子问题,分别求解子问题的最大子段和,然后合并得到整体的最大子段和。这种方法的时间复杂度为O(n log n),适用于中等规模的数据集。它的优势在于对于更大规模的问题,其效率相对较高。

动态规化:

D[i]表示从i开始的最大字段和。(但我们不是从前往后找字段结束位置)

根据递推公式,我们可知要想求得D[i],就必须知道D[i+1],所以我们从前往后计算。

如下图:以i=12开始的子段和D[12]=X[12]=-1,该子段结束位置Rec[12]=i=12;

当i=11时,D[11+1]<0,所以D[11]=X[11]=7,Rec[i]=i=11;

当i=10时,D[10+1]>0,所以D[10]=X[10]+D[11]=3+7,Rec=i+1=11;


一直到i,我们就找完了所有子段和,接着在子段和中找最大的。

        动态规划采用自底向上的方式,通过迭代计算子问题的最优解,并将结果保存起来,避免了重复计算。这种方法的时间复杂度为O(n),适用于大规模数据集。它的优势在于具有更好的时间效率,但相对于分治法,实现稍显复杂。

实验分析

暴力破解

源码:

//暴力破解

int sum1(int arr[],int len) {

    int sum=0;

    for (int i = 0; i < len; i++) {

         int this_sum = 0;

         for (int j = i; j < len; j++) {

             this_sum += arr[j];

             if (this_sum > sum) {

                  sum = this_sum;

             }

         }

    }

    return sum;

}

分治法:

//分治法

int maxSubSum(int a[], int left, int right) {



    int sum = 0;

    if (left == right) {

         sum = a[left] > 0 ? a[left] : 0;

    }

    else {



         int center = (left + right) / 2;

         int leftSum = maxSubSum(a, left, center);

         int rightSum = maxSubSum(a, center + 1, right);



         int s1 = 0;

         int lefts = 0;

         for (int i = center; i >= left; i--) {



             lefts += a[i];

             if (lefts > s1) s1 = lefts;

         }



         int s2 = 0;

         int rights = 0;

         for (int i = center + 1; i < right; i++) {



             rights += a[i];

             if (rights > s2)  s2 = rights;

         }

         sum = s1 + s2;

         if (sum < leftSum) sum = leftSum;

         if (sum < rightSum) sum = rightSum;

    }

    return sum;

}



int maxSum(int a[], int n) {

    return maxSubSum(a, 0, n - 1);

}

动态规划:

//动态规划

int sum2(int arr[],int len)

{

    int sum=0;

    int b=0;

    int left=0;

    int right=0;

    for (int i = 0; i < len; i++) {

         if (b > 0) {

             b += arr[i];

             right = i;

         }

         else {

             b = arr[i];



         }



         if (sum < b) {

             sum = b;



         }

    }

   

    return sum;



}



实验分析:

测试了2000个数据,除了暴力破解比较慢用了8ms,其他的都不足1ms。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/252529.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

scala方法与函数

定义方法定义函数方法和函数的区别scala的方法函数操作 1.9 方法与函数 1.9.1 定义方法 定义方法的基本格式是&#xff1a; def 方法名称&#xff08;参数列表&#xff09;&#xff1a;返回值类型 方法体 def add(x: Int, y: Int): Int x y println(add(1, 2)) // 3 //也…

html第一阶段到底再讲什么

通过这个方式来学习javaweb的全部框架 服务器数据库和连接前端和后端的方式

I Doc View在线文档预览系统cms.json存在RCE漏洞

文章目录 产品简介漏洞概述指纹识别漏洞利用修复建议 产品简介 i Doc View是一个在线文档解析应用&#xff0c;旨在提供便捷的文件查看和编辑服务。 漏洞概述 iDocView是一个在线文档I Doc View在线文档预览系统cmd.json 处存在命令执行漏洞&#xff0c;攻击者可通过此漏洞获…

Windows本地的RabbitMQ服务怎么在Docker for Windows的容器中使用

1. 进入管理界面 windows安装过程请访问&#xff1a;Windows安装RabbitMQ、添加PHP的AMQP扩展 浏览器访问&#xff1a;http://127.0.0.1:15672/ 2. 创建虚拟主机 上面访问的是 RabbitMQ 的管理界面&#xff0c;可以在这个界面上进行一些操作&#xff0c;比如创建虚拟主机、…

抖音跑腿小程序开发指南:从零开始到上线

如今&#xff0c;抖音跑腿小程序的开发已经成为一项具有巨大潜力的领域。本文将为您提供一份详尽的开发指南&#xff0c;从零开始引导您完成一个成功的抖音跑腿小程序的开发和上线过程。 第一步&#xff1a;确定目标和需求 了解用户的期望&#xff0c;确定小程序的功能模块&a…

凸函数笔记(2)

目录 4. 凸函数的结构5. 拟凸函数5.1 定义与等价刻画5.2 可微函数的拟凸性判定5.3 保拟凸运算练习 4. 凸函数的结构 本节将证明&#xff1a; 给定凸函数 f f f 的一个相对内点 x x x, 必存在过 ( x , f ( x ) ) (x,f(x)) (x,f(x)) 的一个仿射函数 y f ( x ) v T ( y − x…

Lumerical 技巧------Plot in New Window

Lumerical 技巧------Plot in New Window 简介正文 简介 当我们在计算模式分布后想要观察模式对应的图像&#xff0c;为了清晰地观察到一些细节&#xff0c;我们可以通过点击图像绘制窗口的 Plot in New Window 按键来实现。 正文 默认模式绘制图像如下&#xff1a; 窗口很…

C++中的继承(一)

文章目录 前言概念访问限定符基类和派生类的赋值转换继承中的作用域派生类的默认成员函数构造函数 拷贝构造析构函数 继承的其他一些细节 前言 我们之前说过&#xff0c;继承是面向对象的三大特性。 面向对象的三大特性&#xff1a; 封装、继承、多态。 封装在类和对象体现出…

【unity小技巧】最简单的FPS游戏准心跳动动画控制

最终效果 文章目录 最终效果前言绘制简单的准心UI实现不同状态准心大小变化射击准心跳动的效果完结 前言 游戏准心跳动在FPS也是比较常用的功能&#xff0c;可以增强游戏反馈和打击感&#xff0c;丰富游戏内容&#xff0c;实现准心跳动的方式五花八门&#xff0c;我不知道别人…

Redis Streams 实现消息队列

简单介绍 Redis中有三种消息队列模式&#xff1a; 可以看出&#xff0c;作为Redis 5.0 引入的专门为消息队列设计的数据类型&#xff0c;Stream 功能更加健全&#xff0c;更适合做消息队列分发。 Stream 可以包含 0个 到 n个元素的有序队列&#xff0c;并根据ID的大小进行排序…

【CMU 15-445】Lecture 10: Sorting Aggregations Algorithms 学习笔记

Sorting & Aggregations Algorithms SortingTop-N Heap SortExternal Merge Sort2-WAY External Merge SortK-WAY External Merge SortDouble Buffering Optimization AggregationsSortingHashing 本节课主要介绍的是数据库系统中的排序算法以及聚合算法 Sorting 排序算法…

数据结构期末考题之001

算法复杂度就是n&#xff08;0&#xff09;

JdbcTemplate

环境搭建 依赖 <!-- Oracle11g 连接驱动依赖。这里是个坑&#xff0c;官方提供的不能用 --><dependency><groupId>cn.easyproject</groupId><artifactId>ojdbc6</artifactId><version>12.1.0.2.0</version></dependency&g…

20231217在Canonical 官网下载ubuntu-20.04.6以及通过rufus-4.3p写入U盘作为安装盘

20231217在Canonical 官网下载ubuntu-20.04.6以及通过rufus-4.3p写入U盘作为安装盘 2023/12/17 11:45 百度搜索&#xff1a;https://ubuntu.com/ https://ubuntu.com/engage/migrating-from-rhel-centos-to-ubuntu-public-cloud?utm_sourcetakeover http://releases.ubuntu.co…

从关键新闻和最新技术看AI行业发展(2023.12.4-12.17第十二期) |【WeThinkIn老实人报】

写在前面 【WeThinkIn老实人报】旨在整理&挖掘AI行业的关键新闻和最新技术&#xff0c;同时Rocky会对这些关键信息进行解读&#xff0c;力求让读者们能从容跟随AI科技潮流。也欢迎大家提出宝贵的优化建议&#xff0c;一起交流学习&#x1f4aa; 大家好&#xff0c;我是Rock…

软件设计规约和评审

软件设计规约 概要设计规约&#xff1a;这是面向软件开发者的文档&#xff0c;主要作为软件项目管理人员、系统分析人员与设计人员之间交流的媒介。它指明了软件的组织结构&#xff0c;主要内容包括&#xff1a; 系统环境&#xff1a;硬件、软件接口与人机界面&#xff1b;外部…

半导体设备之外延炉简述

半导体设备对整个半导体行业起着重要的支撑作用。因半导体制造工艺复杂&#xff0c;各个环节需要的设备也不同&#xff0c;从流程工序分类来看&#xff0c;半导体设备主要可分为晶圆制造设备&#xff08;前道工序&#xff09;、封装测试设备&#xff08;后道工序&#xff09;等…

自动驾驶学习笔记(二十)——Planning算法

#Apollo开发者# 学习课程的传送门如下&#xff0c;当您也准备学习自动驾驶时&#xff0c;可以和我一同前往&#xff1a; 《自动驾驶新人之旅》免费课程—> 传送门 《Apollo 社区开发者圆桌会》免费报名—>传送门 文章目录 前言 参考线平滑 双层状态机 EM Planner …

724. 寻找数组的中心下标

代码&#xff1a; class Solution {public int pivotIndex(int[] nums) {int last0; //放前一个下标的左右差值int now0; //放当前下标的左右差值// 0 位于边界&#xff0c;先算出 0 下标左右的差值for(int i1;i<nums.length;i){lastnums[i];}//判断是否 0 下标就已…

大模型自定义算子优化方案学习笔记:CUDA算子定义、算子编译、正反向梯度实现

01算子优化的意义 随着大模型应用的普及以及算力紧缺&#xff0c;下一步对于计算性能的追求一定是技术的核心方向。因为目前大模型的计算逻辑是由一个个独立的算子或者说OP正反向求导实现的&#xff0c;底层往往调用的是GPU提供的CUDA的驱动程序。如果不能对于整个计算过程学习…