[Kadane算法,前缀和思想]元素和最大的子矩阵

元素和最大的子矩阵

题目描述

输入一个n级方阵,请找到此矩阵的一个子矩阵,此子矩阵的各个元素的和是所有子矩阵中最大的,输出这个子矩阵及这个最大的和。

关于输入

首先输入方阵的级数n,
然后输入方阵中各个元素。

关于输出

输出子矩阵,
最后一行输出这个子矩阵的元素的和。

例子输入
4
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
例子输出
9 2
-4 1
-1 8
15
解题分析

这个程序是一个求解最大子矩阵和的问题。可以使用动态规划和Kadane算法。这个问题可以描述为:给定一个二维数组,找出其中的一个子矩阵,使得这个子矩阵中所有元素的和最大。

这个程序的主要思路如下:

1. 读取一个整数`n`,然后读取一个`n`x`n`的整数矩阵`a`。

2. 计算`total`数组,`total[i][j]`表示从`a[0][j]`到`a[i][j]`的元素之和。如果`i`为0,`total[i][j]`就等于`a[i][j]`,否则`total[i][j]`就等于`total[i-1][j]+a[i][j]`。

3. 遍历所有可能的子矩阵。对于每一个子矩阵,计算其元素之和,然后与当前最大的子矩阵和进行比较。如果新的子矩阵和更大,就更新最大的子矩阵和,以及对应的子矩阵的左上角和右下角的坐标。

4. 在计算子矩阵和的过程中,使用了Kadane算法。Kadane算法可以在O(n)的时间复杂度内求解最大子数组和的问题。在这个程序中,Kadane算法被用来求解每一行元素之和的最大值。

5. 最后,打印出最大子矩阵和,以及对应的子矩阵的元素。

Kadane算法是一个用于解决最大子数组和问题的动态规划算法。最大子数组和问题可以描述为:在一个一维数组中,找出一个连续的子数组,使得这个子数组中所有元素的和最大。

Kadane算法的基本思想是,对于数组中的每个位置,计算以该位置为结束点的所有子数组中,和最大的那个子数组的和。然后,从这些和中找出最大的那个,就是最大子数组和。

具体来说,算法的步骤如下:

1. 初始化两个变量,`max_so_far`和`max_ending_here`,都设为数组的第一个元素。`max_so_far`表示到目前为止找到的最大子数组和,`max_ending_here`表示以当前位置为结束点的子数组的最大和。

2. 对于数组中的每个位置,首先计算`max_ending_here + array[i]`,然后与`array[i]`比较,取较大的那个作为新的`max_ending_here`。这一步表示,如果加上当前元素能使子数组和更大,就加上当前元素,否则就从当前元素开始新的子数组。

3. 然后,比较`max_so_far`和`max_ending_here`,取较大的那个作为新的`max_so_far`。这一步表示,如果`max_ending_here`比`max_so_far`大,就更新`max_so_far`。

4. 重复上述步骤,直到遍历完数组。

5. 最后,`max_so_far`就是最大子数组和。

Kadane算法的时间复杂度是O(n),因为它只需要遍历一次数组。这使得它在处理大规模数据时非常高效。

举个例子:

让我们通过一些具体的例子来理解Kadane算法。

假设我们有一个数组`{-2, -3, 4, -1, -2, 1, 5, -3}`,我们想找到这个数组中,和最大的子数组。

我们可以按照Kadane算法的步骤来操作:

1. 初始化`max_so_far`和`max_ending_here`为数组的第一个元素`-2`。

2. 对于数组中的第二个元素`-3`,我们先计算`max_ending_here + array[i]`,得到`-2 - 3 = -5`,然后与`-3`比较,取较大的那个作为新的`max_ending_here`,所以`max_ending_here`更新为`-3`。然后,比较`max_so_far`和`max_ending_here`,取较大的那个作为新的`max_so_far`,所以`max_so_far`保持不变,还是`-2`。

3. 对于数组中的第三个元素`4`,我们先计算`max_ending_here + array[i]`,得到`-3 + 4 = 1`,然后与`4`比较,取较大的那个作为新的`max_ending_here`,所以`max_ending_here`更新为`4`。然后,比较`max_so_far`和`max_ending_here`,取较大的那个作为新的`max_so_far`,所以`max_so_far`更新为`4`。

4. 以此类推,我们可以得到以下的结果:

   ```
   i = 3, array[i] = -1, max_ending_here = 3, max_so_far = 4
   i = 4, array[i] = -2, max_ending_here = 1, max_so_far = 4
   i = 5, array[i] = 1, max_ending_here = 2, max_so_far = 4
   i = 6, array[i] = 5, max_ending_here = 7, max_so_far = 7
   i = 7, array[i] = -3, max_ending_here = 4, max_so_far = 7
   ```

5. 最后,我们得到的`max_so_far`就是最大子数组和,也就是`7`。这个最大和的子数组是`{4, -1, -2, 1, 5}`。

通过这个例子,我们可以看到,Kadane算法可以有效地找到最大子数组和,而且只需要遍历一次数组。

代码实现
#include <iostream>
using namespace std;int a[1000][1000];
int total[1000][1000];
int result[1000];
int n;int getmax(int &start,int &end){int local_start=0;int maxSum=result[0];int cur_max=result[0];for(int i=1;i<n;i++){if(result[i]>cur_max+result[i]){cur_max=result[i];local_start=i;}else{cur_max+=result[i];}if(cur_max>maxSum){start=local_start;end=i;maxSum=cur_max;}}return maxSum;
}int main() {cin>>n;for(int i=0;i<n;i++)for(int j=0;j<n;j++){cin>>a[i][j];}for(int i=0;i<n;i++)for(int j=0;j<n;j++){if(i==0) total[i][j]=a[i][j];else total[i][j]=total[i-1][j]+a[i][j];}int top=0,bottom=0,left=0,right=0;int maxSum=total[0][0];for(int i=0;i<n;i++)for(int j=i;j<n;j++){int start=0,end=0;for(int k=0;k<n;k++){if(i==0){result[k]=total[j][k];}else{result[k]=total[j][k]-total[i-1][k];}}int sum=getmax(start,end);if(sum>maxSum){maxSum=sum;top=i; bottom=j; left=start; right=end;}}for(int i=top;i<=bottom;i++)for(int j=left;j<=right;j++){cout<<a[i][j];if(j!=right) cout<<" ";else cout<<endl;}cout<<maxSum<<endl;return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

车载蓝牙音乐流程简单分析

关键类&#xff1a; /packages/apps/Bluetooth/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java /packages/apps/Bluetooth/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java 一、音乐播放状态 CPP中通过JNI接口将接从…

Python中利用遗传算法探索迷宫出路

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 当处理迷宫问题时&#xff0c;遗传算法提供了一种创新的解决方案。本文将深入探讨如何运用Python和遗传算法来解决迷宫问题。迷宫问题是一个经典的寻路问题&#xff0c;寻找从起点到终点的最佳路径。遗传算法是一…

ActiveMQ断线重连技巧,即通信高可用的配置

最近在做一个内部应用的时候&#xff0c;应用到了ActiveMQ作为服务之间消息传递&#xff0c;解耦服务之间的关联&#xff0c;但是在应用的过程中遇到了连接断线无法重连的问题&#xff0c;下面基于这个问题&#xff0c;深入了解一下ActiveMQ的一些相关原理和知识。 一、前置知…

springboot2 在Java项目中你们是如何配置时间格式响应给前端呢

在 Spring Boot 2 项目中配置时间格式&#xff0c;通常可以通过配置文件&#xff08;application.properties 或 application.yml&#xff09;或者通过 Java 代码进行配置。以下是两种常见的配置方式&#xff1a; 1. 通过配置文件配置时间格式&#xff1a; 在 application.pr…

mybaties plus插入数据,自动回显 机制

结论&#xff1a;mybaties plus会将库里数据自动回显到 要插入的数据上 测试表格 SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0;-- 表结构 DROP TABLE IF EXISTS t_stu; CREATE TABLE t_stu (id int NOT NULL COMMENT id,name varchar(255) CHARACTER SET utf8mb4 COLLATE…

【PyTorch】计算设备

文章目录 1. 介绍2. 查询和使用 1. 介绍 CPU设备意味着所有物理CPU和内存&#xff0c; 这意味着PyTorch的计算将尝试使用所有CPU核心。可以用以下方式表示&#xff1a; torch.device(cpu) GPU设备只代表一个GPU和相应的显存。 torch.device(cuda)如果有多个GPU&#xff0c;我们…

Java解决矩阵对角线元素的和问题

Java解决矩阵对角线元素的和问题 01 题目 给你一个正方形矩阵 mat&#xff0c;请你返回矩阵对角线元素的和。 请你返回在矩阵主对角线上的元素和副对角线上且不在主对角线上元素的和。 示例 1&#xff1a; 输入&#xff1a;mat [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a…

为什么流量对店铺转化率重要?亚马逊、速卖通等跨境卖家通过自养号测评提升店铺转化率

亚马逊、速卖通等电商平台卖家非常清楚流量对店铺转化率的重要性&#xff0c;测评补单在跨境电商卖家中扮演着重要的角色&#xff0c;是一种必要的运营手段之一。在追求更好的产品曝光和更高的转化率时&#xff0c;Listing的排名是关键因素之一。而在各个平台的Listing中&#…

正确使用AFX_MANAGE_STATE宏管理MFC模块状态, AFX_MANAGE_STATE宏作用,真的很重要!!!

简介&#xff1a; 在使用 MFC&#xff08;Microsoft Foundation Classes&#xff09;开发 DLL&#xff08;动态链接库&#xff09;时&#xff0c;正确管理 MFC 模块状态是确保功能正常运行的关键。本文将深入探讨使用 AFX_MANAGE_STATE 宏的重要性&#xff0c;以及在 DLL 中正确…

连接Redis报错解决方案

连接Redis报错&解决方案 问题描述&#xff1a;Could not connect to Redis at 127.0.0.1:6379: 由于目标计算机积极拒绝&#xff0c;无法连接。 问题原因&#xff1a;redis启动方式不正确 解决方案&#xff1a; 在redis根目录下打开命令行窗口&#xff0c;输入命令redi…

听GPT 讲Rust源代码--src/tools(12)

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs 在Rust源代码中&#xff0c;rust/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs文件的作用是定义和解析rust-analyzer的配置文件。该文件包含了各种配置项的数据结构和枚举类型&#xf…

MQTT主题、通配符和最佳实践

MQTT主题在MQTT生态系统非常重要&#xff0c;因为代理&#xff08;broker&#xff09;依赖主题确定哪个客户端接收指定的主题。本文我们将聚集MQTT主题、MQTT通配符&#xff0c;详细讨论使用它们的最佳实践&#xff0c;也会探究SYS主题&#xff0c;提供给代理&#xff08;broke…

【npm | npm常用命令及镜像设置】

npm常用命令及镜像设置 概述常用命令对比本地安装全局安装--save &#xff08;或 -S&#xff09;--save-dev &#xff08;或 -D&#xff09; 镜像设置设置镜像方法切换回npm官方镜像选择镜像源 主页传送门&#xff1a;&#x1f4c0; 传送 概述 npm致力于让 JavaScript 开发变得…

iOS——UIPickerView选择器

UIPickerView UIPickerView是 iOS 开发中常用的用户界面组件之一&#xff0c;用于在垂直方向上显示一个滚动的列表&#xff0c;用户可以通过滚动选择其中的一项。 UIPickerView的协议方法 UIPickerView和UItableView差不多&#xff0c;UIPickerView也要设置代理和数据源。UI…

fl studio2024试用版本如何汉化中文?

fl studio2024全称Fruity Loops Studio2024&#xff0c;这款软件也被人们亲切的称之为水果&#xff0c;它是一款功能强大的音乐创作编辑软件&#xff0c;拥有全功能的录音室&#xff0c;大混音盘以及先进的音乐制作工具&#xff0c;用户通过使用该软件&#xff0c;就可以轻松制…

git上传流程

git安装网址&#xff1a;https://git-scm.com 如果您要将本地文件夹上传到名为"compiling"的GitHub仓库&#xff0c;可以按照以下步骤进行操作&#xff1a; 1.安装无脑下一步 2.cd到想上传的文件夹的上一级目录 2.初始化Git仓库&#xff1a;git init 设置分支&a…

C++特殊类设计

1.设计不能被拷贝的类 解析&#xff1a;拷贝只会放生在两个场景中 拷贝构造函数赋值运算符重载 因此想要让一个类禁止拷贝&#xff0c; 就需让该类不能调用“拷贝构造函数”以及“赋值运算符重载”&#xff0c;而C11提供的delete重载关键字可以让这件事情变得更加简单。 1.1.C9…

stl库之list链表与例题

stl中的list是双向链表&#xff0c;优点在于插入/删除元素方便&#xff0c;缺点是随机访问元素时间长 所需头文件&#xff1a;#include <list> 初始化 list<类型名> 变量名 定义一个int类型的变量a list<int> a; 在末尾插入元素 a.push_back(i); 在开…

LeetCode 每日一题 Day 8 || 简单枚举

2048. 下一个更大的数值平衡数 如果整数 x 满足&#xff1a;对于每个数位 d &#xff0c;这个数位 恰好 在 x 中出现 d 次。那么整数 x 就是一个 数值平衡数 。 给你一个整数 n &#xff0c;请你返回 严格大于 n 的 最小数值平衡数 。 示例 1&#xff1a; 输入&#xff1a;n …

Error: Cannot find module ‘@npmcli/config‘ 最新解决办法

看了网上许多这个问题的小伙伴&#xff0c;都是降级node版本来解决的。但是降级并不是我想要的结果。 真正的解决办法就是更新nvm&#xff0c;将你的nvm升级到最新版本&#xff0c;然后卸载掉npm报错的node版本&#xff0c;重新安装即可使用。 解决办法&#xff1a;更新nvm nv…