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

news2024/10/10 4:56:28

前缀和算法(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.coloradmin.cn/o/2195363.html

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

相关文章

告别音乐小白!字节跳动AI音乐创作工具,让你一键变作曲家!

还在羡慕别人能创作动听的音乐&#xff1f;五音不全的你&#xff0c;也梦想着谱写属于自己的乐章&#xff1f;现在&#xff0c;机会来了&#xff01;字节跳动推出了一款AI音乐创作工具——抖音推出的海绵音乐&#xff0c;它能让你轻松一键创作音乐&#xff0c;即使是“音乐小白…

海外科技新闻媒体与商业媒体:垂直网站的魅力与软文分发

海外科技新闻媒体与商业媒体&#xff1a;垂直网站的魅力与软文分发 在信息爆炸的时代&#xff0c;如何有效地传递品牌信息并提高知名度成为了许多企业的重要课题。在这个过程中&#xff0c;海外科技新闻媒体与商业媒体的垂直网站扮演了重要角色&#xff0c;而软文分发则因其独特…

笔试题总结

1.对于线性表的描述&#xff1a;存储空间不一定是连续&#xff0c;且各元素的存储顺序是任意的 2.虚函数的定义&#xff1a;函数的返回值参数不定&#xff0c; 声明&#xff1a; 类型&#xff0c;返回这类型 名字&#xff08;&#xff09;&#xff1b; 例如声明一个虚函数&a…

计算机毕业设计 基于Python的豆果美食推荐系统的设计与实现 Python+Django+Vue 前后端分离 附源码 讲解 文档

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

JavaScript(JS)基础(一)

1、JavaScript&#xff08;JS&#xff09;简介 JavaScript 是一门跨平台、面向对象的脚本语言&#xff0c;它能使网页可交互&#xff08;例如拥有复杂的动画&#xff0c;可点击的按钮&#xff0c;通俗的菜单等&#xff09;。另外还有高级的服务端 Javascript 版本&#xff0c;例…

1.Python 引入(字面量、注释、变量、数据类型、数据类型转换、标识符、运算符、字符串扩展)

一、字面量 1、基本介绍 在代码中&#xff0c;被写直接下来的、不需要通过变量存储的值&#xff0c;称之为字面量 2、常用值类型 类型说明数字&#xff08;Number&#xff09;整数&#xff08;int&#xff09;&#xff0c;例如&#xff1a;10、-10浮点数&#xff08;float&…

Linux 检查一个文件是静态链接还是动态链接的方法

一、file 指令示例 在 Linux 系统中&#xff0c;可以使用 file 命令 来查看一个可执行文件是静态链接的还是动态链接的。 使用方式 file executable_file创建 hello_test.c 文件&#xff0c;测试代码如下&#xff1a; #include <stdio.h> int main(void){ printf(&q…

xss-labs靶场第一关测试报告

目录 一、测试环境 1、系统环境 2、使用工具/软件 二、测试目的 三、操作过程 1、注入点寻找 2、使用hackbar进行payload测试 3、绕过结果 四、源代码分析 五、结论 一、测试环境 1、系统环境 渗透机&#xff1a;本机(127.0.0.1) 靶 机&#xff1a;本机(127.0.0.…

2-115 基于matlab的瞬态提取变换(TET)时频分析

基于matlab的瞬态提取变换&#xff08;TET&#xff09;时频分析&#xff0c;瞬态提取变换是一种比较新的TFA方法。该方法的分辨率较高&#xff0c;能够较好地提取出故障的瞬态特征&#xff0c;用于故障诊断领域。通过对原始振动信号设置不同信噪比噪声&#xff0c;对该方法的抗…

国庆作业

day1 1.开发环境 Linux系统GCCFDBmakefilesqlite3 2.功能描述 项目功能: 服务器&#xff1a;处理客户端的请求&#xff0c;并将数据存入数据库中&#xff0c;客户端请求的数据从数据库进行获取&#xff0c;服务器转发给客户端。 用户客户端&#xff1a;实现账号的注册、登…

draw.io 设置默认字体及添加常用字体

需求描述 draw.io 是一个比较好的开源免费画图软件。但是其添加容器或者文本框时默认的字体是 Helvetica&#xff0c;一般的期刊、会议论文或者学位论文要求的英文字体是 Times New Roman&#xff0c;中文字体是 宋体&#xff0c;所以一般需要在文本字体选项里的下拉列表选择 …

2024 全新洞察:性格色彩报告 API 接口登场

近年来&#xff0c;人工智能技术的快速发展与应用&#xff0c;为我们的生活带来了诸多便利。其中&#xff0c;性格色彩报告 API 接口的登场&#xff0c;无疑是为我们了解自身性格特点提供了一种全新的方式。 性格色彩报告 API 接口&#xff0c;是一项基于性格色彩题库答案的技…

鸿蒙next开启地图服务

一般手机软件有的都会有开启地图功能&#xff0c;这里说一下怎么开启地图服务 1、 首先你需要配置一些东西&#xff0c;在华为的agc平台上&#xff0c;下边链接就是详细的教程 https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/map-config-agc-V5 我说一下你…

基于LORA的一主多从监测系统_框架搭建

第一节、框架搭建 打开CubeMAX&#xff0c;选择好芯片&#xff0c;进行基础配置 第一步、先配置时钟源 第二步、配置SYS选项 配置debug口以及计数器源&#xff0c;我这里选择TIM1 第三步、选择I2C接口 配置如下即可&#xff0c;默认配置不用改 第四步、串口选择 我们这里使…

2024年超火的AI绘画项目,多重变现方法,日赚1000+

一&#xff0e;项目介绍 绘画是一个很大的领域&#xff0c;今天讲是壁纸头像类的细分赛道&#xff0c;它可以说是一个经久不衰的项目。今年最火的项目肯定是AI&#xff0c;这个项目的核心是将AI生成的头像或壁纸上传到抖音或其他平台上进行变现。这个项目的变现渠道非常多&…

基于STM32的智能台灯设计

1. 设计目的与意义 1.1设计目的 设计一个采用220v交流电进行供电&#xff0c;具备显示屏能够实时显示日期&#xff08;年、月、日和星期&#xff09;&#xff0c;时间&#xff08;小时、分钟、秒&#xff09;和温度&#xff08;摄氏度&#xff09;&#xff0c;能够通过语音交…

github项目——howtocook

github偶然发现的一个项目&#xff0c;无关编程 &#xff0c;只教你做菜&#x1f602; 参与其中&#xff0c;简历就可以写上github热门项目贡献者&#x1f602; 66.7K stars,深的程序员喜爱&#xff01;甚至搞了个专门的域名网站。。。 菜品还有专门的配图和难度系数&#xff0…

水务行业的数字化转型之路:四大挑战与展望

随着数字时代的全面到来&#xff0c;各行各业都在积极探索数字化转型的路径&#xff0c;而作为国民经济命脉之一的水务行业也不例外。水务行业的数字化转型不仅是技术革新的必然趋势&#xff0c;更是提升水资源管理效率、保障水安全、促进生态文明建设的关键举措。然而&#xf…

tick数据合成k线的完整过程(含源代码)

tick数据合成k线的完整过程&#xff08;含源代码&#xff09; 写在前面tick 数据的选择行情结构体字段tick 行情示例 批量合成1分钟k线方式增量合成1分钟k线方式k线分钟级别扩展源码获取方式 写在前面 码上君量化互助社群已建立&#xff0c;所有源码免费对社群成员开放&#x…

鹏哥C语言自定义笔记重点(79-)

79.动态内存管理 80.使用动态内存管理的常见问题 对5的问题修改: 内存泄露的第一种可能: 第二种可能: 81.下面程序可能出现的问题 解决问题的两种方法: 82. 都是会造成野指针 83.p里面的内容不能进入Test 84.内存泄露问题 85.野指针问题:malloc创建的空间销毁了&#xff0c;但…