C++ 算法学习——1.6 前缀和与二维前缀和算法

前缀和算法(Prefix Sum Algorithm):

  1. 概念前缀和算法通过在遍历数组时计算前缀和(从数组的第一个元素开始累加到当前元素的和),可以在O(1)时间内得到任意区间的子数组和,而不需要重复计算。

  2. 算法步骤

    • 遍历数组,计算每个位置的前缀和,并存储在另一个数组中。
    • 计算任意区间和时,利用前缀和数组直接计算区间两端位置的前缀和之差即可得到区间和。
  3. 应用:前缀和算法常用于解决一维数组中的区间和问题,例如最大子数组和、子数组和为0的最长子数组等。

  4. 构建示例

    for (int i = 1; i < n; i++) {
            prefixSum[i] = prefixSum[i - 1] + nums[i];
        }


二维前缀和算法(2D Prefix Sum Algorithm):

  1. 概念:二维前缀和算法是在二维数组或矩阵上的扩展,用于快速计算矩阵中任意矩形区域的和。

  2. 算法步骤

    • 遍历二维数组,计算每个位置的二维前缀和,即该位置左上方所有元素的和
    • 计算任意矩形区域和时,利用二维前缀和数组可以在O(1)时间内计算出该区域的和。
  3. 应用:二维前缀和算法常用于解决二维矩阵中的区域和问题,例如二维区域和为0的最大子矩阵和、矩形区域和等。

  4. 计算与构建示例

    int getSubmatrixSum(int** prefixSum, int row1, int col1, int row2, int col2) {
        int sum = prefixSum[row2][col2];
        if (row1 > 0) {
            sum -= prefixSum[row1 - 1][col2];
        }
        if (col1 > 0) {
            sum -= prefixSum[row2][col1 - 1];
        }
        if (row1 > 0 && col1 > 0) {
            sum += prefixSum[row1 - 1][col1 - 1];
        }
        return sum;
    }
    int** build2DPrefixSumArray(const int** matrix, int rows, int cols) {
        // 分配内存来存储前缀和数组
        int** prefixSum = new int*[rows];
        for (int i = 0; i < rows; i++) {
            prefixSum[i] = new int[cols];
        }
    
        // 初始化前缀和数组
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                prefixSum[i][j] = 0;
            }
        }
    
        // 计算第一行的前缀和
        for (int j = 0; j < cols; j++) {
            prefixSum[0][j] = matrix[0][j]+prefixSum[0][j-1];
        }
    
        // 计算第一列的前缀和
        for (int i = 1; i < rows; i++) {
            prefixSum[i][0] = prefixSum[i - 1][0] + matrix[i][0];
        }
    
        // 计算其他位置的前缀和
        for (int i = 1; i < rows; i++) {
            for (int j = 1; j < cols; j++) {
                prefixSum[i][j] = matrix[i][j] + prefixSum[i - 1][j] + prefixSum[i][j - 1] - prefixSum[i - 1][j - 1];
            }
        }
    
        return prefixSum;
    }

P1. 洛谷p1719最大加权矩形 

#include <iostream>
#include <cmath>
using namespace std;

int getSubmatrixSum(int** prefixSum, int row1, int col1, int row2, int col2) {
    int sum = prefixSum[row2][col2];
    if (row1 > 0) {
        sum -= prefixSum[row1 - 1][col2];
    }
    if (col1 > 0) {
        sum -= prefixSum[row2][col1 - 1];
    }
    if (row1 > 0 && col1 > 0) {
        sum += prefixSum[row1 - 1][col1 - 1];
    }
    return sum;
}

int main() {
    int ans = 0;
    int n;
    cin >> n;
    
    // 创建二维矩阵
    int** mat = new int*[n];
    for (int i = 0; i < n; i++) {
        mat[i] = new int[n];
    }

    // 读取矩阵元素
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cin >> mat[i][j];
        }
    }

    // 创建前缀和数组
    int** prefixSum = new int*[n];
    for (int i = 0; i < n; i++) {
        prefixSum[i] = new int[n];
    }

    // 计算前缀和数组
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            prefixSum[i][j] = mat[i][j];
            if (i > 0) {
                prefixSum[i][j] += prefixSum[i - 1][j];
            }
            if (j > 0) {
                prefixSum[i][j] += prefixSum[i][j - 1];
            }
            if (i > 0 && j > 0) {
                prefixSum[i][j] -= prefixSum[i - 1][j - 1];
            }
        }
    }

    // 计算最大子矩阵和
    for (int row1 = 0; row1 < n; row1++) {
        for (int col1 = 0; col1 < n; col1++) {
            for (int row2 = row1; row2 < n; row2++) {
                for (int col2 = col1; col2 < n; col2++) {
                    ans = max(getSubmatrixSum(prefixSum, row1, col1, row2, col2), ans);
                }
            }
        }
    }

    cout << ans;

    // 释放内存
    for (int i = 0; i < n; i++) {
        delete[] mat[i];
        delete[] prefixSum[i];
    }
    delete[] mat;
    delete[] prefixSum;

    return 0;
}

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

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

相关文章

详解 PDF 转 JPG:简单操作,高效转换

如今&#xff0c;众多软件都已具备将PDF转换为JPG的功能&#xff0c;所以pdf怎么转换成jpg图片已经不难解决了吧。接下来&#xff0c;我想分享几款依然保存在我电脑中&#xff0c;且非常实用的PDF转JPG工具给大家。 1.福昕PDF转换大师 链接一下>>https://www.pdf365.cn…

【2024年10月测试通过】conda下使用虚拟环境安装最新版pytorch2.4+cuda12.4

开头先说重点&#xff1a; 1.采用conda的虚拟环境&#xff0c;会在沙盒环境下安装好所有所需包&#xff0c;而且该虚拟环境拷贝给其他人员可以直接用&#xff0c;很方便。 2.pytorch官网访问不了&#xff0c;有一个国内镜像推荐&#xff0c;地址为PyTorch - PyTorch 中文 3.…

OXO:一款针对Orchestration框架的安全扫描引擎

关于OXO OXO是一款针对Orchestration框架的安全扫描引擎&#xff0c;该工具可以帮助广大研究人员检测Orchestration安全问题&#xff0c;并执行网络侦查、 枚举和指纹识别等操作。 值得一提的是&#xff0c;OXO还提供了数十种其他的协同工具&#xff0c;包括网络扫描代理&…

erlang学习:Linux命令学习10

从百度网盘下载文件 共享百度网盘获得链接 https://pan.baidu.com/s/1iUOTAWr1SRlL2fBZ7lIV拿到链接之后在浏览器中进行下载&#xff0c;可以查看下载链接 右键这些文件即可得到下载链接 类似于长这样 https://bdbl-cm01.baidupcs.com/file/b02f72906b3d0d07130be625eabc76…

出海快报 | “三消+短剧”手游横空出世,黄油相机“出圈”日本市场,从Q1看日本手游市场趋势和机会

编者按&#xff1a;TopOn出海快报栏目为互联网出海从业者梳理出海热点&#xff0c;供大家了解行业最新发展态势。 1.“三消短剧”横空出世&#xff0c;融合创新手游表现亮眼 随着竞争的加剧&#xff0c;新产品想要突出重围&#xff0c;只能在游戏中加入额外的元素。第一次打开…

java复制查询数组-cnblog

java数组 复制数组 copyOf(待复制数组,复制后新数组的长度) 如果复制后数组的长度&#xff0c;长于原来数组&#xff0c;多出来的元素会被补0&#xff0c;如果新数组元素少会从第一个元素&#xff0c;取到指定元素长度 package nb;import java.util.Arrays;public class co…

行业预测 60TB 硬盘将于 2028 年到来

在硬盘容量增长停滞了一段时间后&#xff0c;在短短四年内从目前的 30TB 增长到 60TB 将是一个巨大的增长。 然而&#xff0c;这正是 IEEE 最新发布的《海量数据存储设备和系统国际路线图》报告所预测的。 该路线图预计 2028 年市场上将出现 60TB 的硬盘驱动器。 这一增长将由一…

Flet介绍:平替PyQt的好用跨平台Python UI框架

随着Python在各个领域的广泛应用&#xff0c;特别是在数据科学和Web开发领域&#xff0c;对于一个简单易用且功能强大的用户界面&#xff08;UI&#xff09;开发工具的需求日益增长。传统的Python GUI库如Tkinter、PyQt虽然功能强大&#xff0c;但在易用性和现代感方面略显不足…

计算机毕业设计 | SpringBoot 房屋租赁网 租房买房卖房平台(附源码)

1&#xff0c;绪论 1.1 背景调研 在房地产行业持续火热的当今环境下&#xff0c;房地产行业和互联网行业协同发展&#xff0c;互相促进融合已经成为一种趋势和潮流。本项目实现了在线房产平台的功能&#xff0c;多种技术的灵活运用使得项目具备很好的用户体验感。 这个项目的…

Authentication Lab | Client Side Auth

关注这个靶场的其它相关笔记&#xff1a;Authentication Lab —— 靶场笔记合集-CSDN博客 0x01&#xff1a;Client Side Auth 前情提要 有些时候&#xff0c;开发人员会将身份验证的逻辑写于前端&#xff0c;这样写是十分不安全的&#xff0c;因为前端的代码几乎全部都是可见的…

C#多线程基本使用和探讨

线程是并发编程的基础概念之一。在现代应用程序中&#xff0c;我们通常需要执行多个任务并行处理&#xff0c;以提高性能。C# 提供了多种并发编程工具&#xff0c;如Thread、Task、异步编程和Parallel等。 Thread 类 Thread 类是最基本的线程实现方法。使用Thread类&#xff0…

快递查询软件:实现单号识别与批量物流查询的高效工具

随着网络购物的普及&#xff0c;快递物流行业迎来了前所未有的发展机遇&#xff0c;同时也面临着巨大的挑战。跟踪物流信息成为一个难题&#xff0c;因此&#xff0c;快递查询软件的核心功能之一便是单号识别。传统的快递单号输入方式繁琐且易出错在此背景下&#xff0c;快递查…

代码随想录day22:回溯part4

491.递增子序列 class Solution {List<List<Integer>> result new ArrayList<>();List<Integer> path new ArrayList<>();public List<List<Integer>> findSubsequences(int[] nums) {backTracking(nums, 0);return result;}priv…

如何基于 RLHF 来优化 ChatGPT 类型的大语言模型

&#x1f6b4;前言 对于ChatGPT来说&#xff0c;RLHF是其训练的核心。所谓RLHF&#xff0c;即Reinforcement Learning with Human Feedback&#xff0c;基于人类反馈的强化学习。这项技术通过结合模型自身的生成能力和人类专家的反馈&#xff0c;为改进文本生成质量提供了新的…

计算机网络-------重传、TCP流量控制、拥塞控制

重传、滑动窗口、流量控制、拥塞避免 重传机制 超时重传 发送方在发送数据时会启动一个定时器&#xff0c;当超过指定的时间之后&#xff0c;还没接收到接收方的ACK确认应答报文&#xff0c;就会重传该数据 快重传 当发送方收到接收方三个连续的ack之后说明发送方发送的报…

关于Amazon Linux 2023的版本及包管理器

在亚马逊上创建EC2实例时&#xff0c;会看到有一个Amazon Linux镜像。 那这个镜像与其他Linux有什么关系和区别呢&#xff1f; 网站是介绍&#xff1a;Amazon Linux 2023 是基于 Linux 的现代化通用操作系统&#xff0c;提供 5 年的长期支持。它针对 AWS 进行了优化&#xff0…

《Linux从小白到高手》理论篇:深入理解Linux的计划任务/定时任务

值此国庆佳节&#xff0c;深宅家中&#xff0c;闲来无事&#xff0c;就多写几篇博文。本篇详细深入介绍Linux的计划任务/定时计划。 Linux的计划任务 在很多时候为了自动化管理系统&#xff0c;我们都会用到计划任务&#xff0c;比如关机&#xff0c;重启&#xff0c;备份之类…

详解Java中的BIO、NIO、AIO

1、 详解Java中的BIO、AIO、NIO 1.1、引言 IO流是Java中比较难理解的一个知识点&#xff0c;但是IO流在实际的开发场景中经常会使用到&#xff0c;比如Dubbo底层就是NIO进行通讯。本文将介绍Java发展过程中出现的三种IO&#xff1a;BIO、NIO以及AIO&#xff0c;重点介绍NIO。…

读数据工程之道:设计和构建健壮的数据系统03数据工程生命周期(上)

1. 数据工程生命周期 1.1. 数据领域正在经历新数据技术和实践的爆炸式增长&#xff0c;抽象程度和易用性不断提高 1.2. 由于技术抽象程度的增加&#xff0c;数据工程师将越来越多地成为数据生命周期工程师&#xff0c;根据数据生命周期管理的原则来进行思考和操作 1.3. 数据…

专题十_穷举vs暴搜vs深搜vs回溯vs剪枝_二叉树的深度优先搜索_算法专题详细总结

目录 搜索 vs 深度优先遍历 vs 深度优先搜索 vs 宽度优先遍历 vs 宽度优先搜索 vs 暴搜 1.深度优先遍历 vs 深度优先搜索(dfs) 2.宽度优先遍历 vs 宽度优先搜索(bfs) 2.关系图暴力枚举一遍所有的情况 3.拓展搜索问题全排列 决策树 1. 计算布尔⼆叉树的值&#xff08;medi…