《算法闯关指南:优选算法--前缀和》--25.【模板】前缀和,26.【模板】二维前缀和

《算法闯关指南:优选算法--前缀和》--25.【模板】前缀和,26.【模板】二维前缀和
在这里插入图片描述

🔥草莓熊Lotso:个人主页
❄️个人专栏: 《C++知识分享》《Linux 入门到实践:零基础也能懂》
✨生活是默默的坚持,毅力是永久的享受!


🎬 博主简介:

在这里插入图片描述

文章目录


前言:

聚焦算法题实战,系统讲解三大核心板块:优选算法:剖析动态规划、二分法等高效策略,学会寻找“最优解”。 递归与回溯:掌握问题分解与状态回退,攻克组合、排列等难题。 贪心算法:理解“局部最优”到“全局最优”的思路,解决区间调度等问题 内容以题带点,讲解思路与代码实现,帮助大家快速提升代码能力。

25.【模板】前缀和

题目链接

【模板】前缀和__牛客网

题目描述

在这里插入图片描述


题目示例

在这里插入图片描述

解法(前缀和):

算法思路:

  • 先预处理出来一个 【前缀和】 数组:用 dp[i] 表示:【1,i】 区间所有元素的和,那么 dp[i-1] 里面存的就是 【1,i-1】 区间内所有元素的和,那么:可得递推公式:dp[i]=dp[i-1]+arr[i]
  • 使用前缀和数组,【快速】求出【某一个区间内】所有元素的和:当询问的区间是【l,r】时:区间内所有元素的和为:dp[r]-dp[l-1]

C++算法代码:

#include<iostream>#include<vector>usingnamespace std;intmain(){//1.输入数据int n=0,m=0; cin>>n>>m; vector<int>arr(n+1);for(size_t i=1;i<=n;i++) cin>>arr[i];//2.预处理一个dp数组 vector<longlong>dp(n+1);//防止溢出for(size_t i=1;i<=n;i++) dp[i]=dp[i-1]+arr[i];//3.使用前缀和数组int l=0,r=0;while(m--){ cin>>l>>r; cout<<dp[r]-dp[l-1]<<'\n';}return0;}// 64 位输出请用 printf("%lld")

算法总结&&笔记展示:

笔记字有点丑,大家见谅:

在这里插入图片描述

26.【模板】二维前缀和

题目链接

【模板】二维前缀和__牛客网

题目描述

在这里插入图片描述


题目示例

在这里插入图片描述

解法:

算法思路:

类比于一维数组的形式,如果我们能处理出来从【0,0】位置到【i,j】位置这片区域内所有元素的累加和,就可以在 O(1) 的时间内,搞定矩阵内任意区域内所有元素的累加和。因此我们需要接下来仅需要完成下面两步即可:
第一步:搞出来前缀和矩阵
这里就要用到一维数组里面的扩展知识,我们要在矩阵的最上面和最左边添加上一行和一列0,这样我们久可省去非常多的边界条件的处理,处理后的矩阵就像下面这样:

在这里插入图片描述


这样,我们填写前缀和矩阵数组的时候,下标直接从 1 开始,能大胆使用 i-1j-1 位置的值。

注意:dp 表与原数组 martix 内的元素的映射关系:从 dp 表到 martix 矩阵,横纵坐标减一;从 martix 矩阵到 dp 表,横纵坐标加一;

前缀和矩阵中 sum[i][j] 的含义,以及如何递推二维前缀和方程

  • 黄色部分最简单,它就是数组中的 martix[i-1][j-1](注意坐标的映射关系)
  • 单独求蓝色不好求,因为它不是我们定义的状态表示中的区域,同理,单独的绿也是;
  • 但是如果是红+蓝,正好是我们 dp 数组中 sum[i-1][j] 的值;
  • 同理,如果是红+绿,正好是我们dp数组中 sum[i][j-1] 的值;
  • 如果把上面求的三个值加起来,我们会发现多算了一块红色的,因此直接再单独减掉就可以了那就是 黄+(红+蓝)+(红+绿)-红
  • 红的面积正好也是符合 dp 数组的定义的,即 sum[i-1][j-1]

sum[i][j] 表示,从【0,0】位置到 【i,j】位置这段区域内,所有元素的累加和。对应下图的红色区域:

在这里插入图片描述


递推方程:
其实这个递推方程非常像我们小学做过的求图形面积的题,我们可以将【0,0】位置到【i,j】位置这段区域分解成下面的部分:

在这里插入图片描述


sum[i][j] = 红 + 蓝 + 绿 + 黄,分析一下这四块区域:

综上所述,我们的递推方程就是:
sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + martix[i-1][j-1]

第二步:使用前缀和矩阵
题目的接口中提供的参数是原始矩阵的下标,为了避免下标映射错误,这里直接先把下标映射成 dp 表里面对应的下标:row1++,col1+=,row2++,col2++
接下来分析如何使用这个前缀和矩阵,如下图(注意这里的 rowcol 都处理过了,对应的是 sum 矩阵中的下标):

在这里插入图片描述


对于左上角(row1,col1),右下角(row2,cow2)围成的区域,正好是红色部分。因此我们需要求的就是红色部分的面积,继续分析几个区域:

  • 黄色,能直接求出来,就是 sum[row1 - 1, col1 - 1] (为什么减⼀?因为要剔除掉 row 这一行和 col 这一列)
  • 绿色,直接求不好求,但是和黄色拼起来,正好是 sum 表内 sum[row1 - 1][col2]的数据;
  • 同理,蓝色不好求,但是 蓝 + 黄 = sum[row2][col1 - 1]
  • 再看看整个面积,好求嘛?非常好求,正好是 sum[row2][col2]
  • 那么,红色就 = 整个面积 - 黄 - 绿 - 蓝,但是绿蓝不好求,我们可以这样减:整个面积 -(绿+ 黄 )-(蓝 + 黄),这样相当于多减去了⼀个黄,再加上即可

综上所述:红 = 整个面积 - (绿 + 黄)- (蓝 + 黄)+ 黄,从而可得红色区域内的元素总和为:
sum[row2][col2] - sum[row2][col1 - 1] - sum[row1 - 1][col2] + sum[row1 -1][col1 - 1]

C++算法代码:

#include<iostream>#include<vector>usingnamespace std;intmain(){//1.输入数据int n=0,m=0,q=0; cin>>n>>m>>q; vector<vector<int>>arr(n+1,vector<int>(m+1));for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) cin>>arr[i][j];//2.预处理 vector<vector<longlong>>dp(n+1,vector<longlong>(m+1));for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) dp[i][j]=dp[i-1][j]+dp[i][j-1]+arr[i][j]-dp[i-1][j-1];//3.使用前缀和int x1=0,y1=0,x2=0,y2=0;while(q--){ cin>>x1>>y1>>x2>>y2; cout<<dp[x2][y2]-dp[x1-1][y2]-dp[x2][y1-1]+dp[x1-1][y1-1]<<'\n';}return0;}// 64 位输出请用 printf("%lld")

算法总结&&笔记展示:

笔记字有点丑,大家见谅:

在这里插入图片描述

结尾:

🍓 我是草莓熊 Lotso!若这篇技术干货帮你打通了学习中的卡点: 👀 【关注】跟我一起深耕技术领域,从基础到进阶,见证每一次成长 ❤️ 【点赞】让优质内容被更多人看见,让知识传递更有力量 ⭐ 【收藏】把核心知识点、实战技巧存好,需要时直接查、随时用 💬 【评论】分享你的经验或疑问(比如曾踩过的技术坑?),一起交流避坑 🗳️ 【投票】用你的选择助力社区内容方向,告诉大家哪个技术点最该重点拆解 技术之路难免有困惑,但同行的人会让前进更有方向~愿我们都能在自己专注的领域里,一步步靠近心中的技术目标! 

结语:本文介绍了前缀和算法的核心思想及实现方式。通过预处理构建前缀和数组dp,其中dp[i]表示区间[1,i]内所有元素的和,利用递推公式dp[i]=dp[i-1]+arr[i]快速计算。查询区间[l,r]的和时,只需计算dp[r]-dp[l-1]即可高效获取结果。文章以C++代码演示了该算法的应用,并附有手写笔记说明。前缀和算法适用于频繁区间求和场景,能显著提升计算效率。

✨把这些内容吃透超牛的!放松下吧✨ʕ˘ᴥ˘ʔづきらど

Read more

唤醒80年代记忆:基于百度地图的一次老式天气预报的WebGIS构建之旅

唤醒80年代记忆:基于百度地图的一次老式天气预报的WebGIS构建之旅

目录 一、省会城市信息构建 1、省会城市空间查询 2、Java后台查询 二、Java省会城市天气查询 1、与百度开放平台集成天气 2、响应对象属性介绍 3、省会天气实况展示 三、WebGIS应用构建 1、背景音乐集成 2、城市标记及天气展示 3、城市轮播 4、成果展示 四、总结 前言         在数字技术飞速发展的今天,我们常常沉浸于各种高科技带来的便捷与震撼之中,却容易忽视那些曾经陪伴我们成长、承载着时代记忆的旧事物。80年代的天气预报,便是这样一份珍贵的文化遗产。它以简洁而质朴的方式,传递着天气信息,也传递着那个时代的气息。那种对自然的敬畏、对信息的渴望,以及一家人共同分享的温馨氛围,都深深烙印在我们的记忆中。然而,随着时间的推移,天气预报的形式已经发生了翻天覆地的变化。高清的画面、精准的数据、个性化的推送……这些现代技术带来的便利固然令人欣喜,但也在一定程度上让我们失去了那份对天气预报本身的纯粹情感。于是,

By Ne0inhk
Windows下载、安装并运行MinIO,访问WebUI界面

Windows下载、安装并运行MinIO,访问WebUI界面

MinIO MinIO 是一款基于 Apache License v2.0 开源协议的对象存储服务,兼容 Amazon S3 云存储服务接口,可用于存储海量非结构化数据(如图片、视频、日志文件等)。本教程针对 Windows 系统搭建本地 MinIO 服务,适合开发测试、小型项目部署场景。 下载MinIO 官网下载 访问MinIO中文官网或MinIO英文官网,根据读者的操作系统选择相应的操作系统版本点击MinIO Server/AIStor Server和MinIO Client/AIStor Client的Download按钮下载对应文件。 说明:两版官网域名不同,Server/Client 的文字标题有差异,但下载文件一致;中文官网下载速度更快,优先推荐。 网盘下载 通过网盘分享的文件:Minio 链接: https://pan.baidu.com/s/

By Ne0inhk
【初阶数据结构和算法】八大排序算法之插入排序(直接插入排序、希尔排序及其对比)

【初阶数据结构和算法】八大排序算法之插入排序(直接插入排序、希尔排序及其对比)

文章目录 * 一、常见排序算法分类 * 一、直接插入排序 * 二、希尔排序 * 三、直接插入排序和希尔排序性能对比 一、常见排序算法分类 常见的排序算法有八种,我们简单盘点一下 1. 插入排序:直接插入排序、希尔排序 2. 选择排序:直接选择排序、堆排序 3. 交换排序:冒泡排序、快排 4. 希尔排序 5. 计数排序 以上就是我们常用的八大排序算法,我们会在后面的排序算法部分为大家一一介绍,今天我们要介绍的就是插入排序这一大类排序(更新) 一、直接插入排序 我们先来简单地介绍一下直接插入排序的思想: 直接插⼊排序是⼀种简单的插⼊排序法,其基本思想是:把待排序的记录按其关键码值的⼤小逐个插⼊到⼀个已经排好序的有序序列中,直到所有的记录插⼊完为⽌,得到⼀个新的有序序列,我们举一个简单的例子,

By Ne0inhk

OCR识别效果对比:CRNN与传统算法的视觉差异

OCR识别效果对比:CRNN与传统算法的视觉差异 📖 技术背景:OCR文字识别的核心挑战 光学字符识别(Optical Character Recognition, OCR)是将图像中的文字内容转化为可编辑文本的关键技术,广泛应用于文档数字化、票据处理、车牌识别、智能办公等场景。尽管OCR技术已有数十年发展历史,但在复杂背景、低分辨率、手写体、倾斜排版等现实条件下,识别准确率仍面临巨大挑战。 传统OCR系统通常采用“图像预处理 → 字符分割 → 特征提取 → 分类识别”的流水线式架构。这类方法依赖大量人工设计的规则和几何特征(如边缘检测、投影分析),在理想环境下表现尚可,但面对真实世界中光照不均、字体多样、背景干扰等问题时,鲁棒性显著下降。 随着深度学习的发展,端到端的神经网络模型逐渐取代传统流程,其中 CRNN(Convolutional Recurrent Neural Network) 成为工业界主流的通用OCR解决方案。它通过卷积层提取空间特征、循环层建模序列依赖、CTC(Connectionist Temporal Classification)损失函数实现对齐,

By Ne0inhk