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

代码:
 

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextInt()) { // 注意 while 处理多个 case
           int n=in.nextInt();
           int m=in.nextInt();
           int q=in.nextInt();

           //因为题目中的矩阵下标从 1 开始,而我们创建的数组下标从 0 开始,所以需要留一行
           int[][]arr=new int[n+1][m+1];
           for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                arr[i][j]=in.nextInt();
            }
           }

           //获取前缀和数组 dp
           //记录的是区间数据的总和,很容易溢出,所以用 long 类型
           long[][]dp=new long[n+1][m+1];
           //填充 dp 数组
           for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                dp[i][j]=dp[i][j-1]+dp[i-1][j]-dp[i-1][j-1]+arr[i][j];
            }

           }

           //循环查询 q 次
           while(q>0){
            int x1=in.nextInt();
            int y1=in.nextInt();
            int x2=in.nextInt();
            int y2=in.nextInt();

            //使用 dp 数组
            System.out.println(dp[x2][y2]-dp[x1-1][y2]-dp[x2][y1-1]+dp[x1-1][y1-1]);
            q--;
           }
        }
    }
}

题解:

        题目要求我们获取(x1,y1)~(x2,y2)这个区间内的数据总和,这是一个典型的前缀和问题,如果我们使用暴力解法,我们就需要遍历数组中这个区间的所有数据,查询 q 次我们就需要遍历 q 次,所以时间复杂度会为 O(n*m*q),在该题用暴力解法肯定时间会过长的

        所以我们需要使用前缀和解法,我们可以定义一个前缀和数组 dp ,dp[ i ][ j ] 就代表从(1,1)~ (i,j)这个区间内的数据总和,因为我们要统计从(1,1)到各个位置区间的数据总和,所以 dp 数组的大小和二维数组 arr 的大小相同

        现在我们先先考虑如何填充 dp 数组,然后再考虑如何使用 dp 数组获得结果,dp 数组一般第 0 行和 第 0 列 的数据是手动初始化的,而不是程序填充的,为了避免越界问题(后面说明),所以对于示例 1 来说我们还没填充的 dp 数组如下所示

        0        1        2        3        4        5

0      0        0        0        0        0        0

1      0

2      0

3      0

        因为题目给出的数组下标是从 1 开始的,所以下标带 0 的位置是不存在的,所以前缀和都设为 0 ,这也代表我们在填充 dp[ i ][ j ] 时就已经知道了 dp[ i-1 ][ j-1 ],dp[ i ][ j-1 ],dp[ i-1 ][ j ] 的值,我们如何计算 dp[ i ][ j ] 的值呢?为了方便理解我画了下面的图

        我们想要计算 dp[ i ][ j ] ,即从(1,1)~ (i,j)这个区间内的数据总和,根据右边的图,我们要计算的就是 A+B+C+D 的面积,我们可以将该式子替换为 (A+C)+(A+B)-A+D,A+C 的面积就是 dp[ i ][ j-1 ] 的值,A+B 的面积就是 dp[ i-1 ][ j ] 的值,A 的面积就是 dp[ i-1 ][ j-1 ] 的值,D 的面积就是 arr[ i ][ j ] 的值

        所以我们可以得出式子 dp[ i ][ j ] =  dp[ i ][ j-1 ] + dp[ i-1 ][ j ] - dp[ i-1 ][ j-1 ] + arr[ i ][ j ],填充 dp 数组的顺序是先 从左到右 再 从上到下 ,根据该式子,当 i=0 或 j=0 时就会有 -1 的下标,就存在越界问题

        现在得出了 dp 数组的填充式子,我们再研究如何通过 dp 数组得到结果便解出该题,为了方便理解,我画了下面的图

        如上图,我们想要获取(x1,y1)~(x2,y2)这个区间内的数据总和 x ,相当于要计算 

s - A - B - C 的值,我们将该表达式修改为 s - (A+B) - (A+C) + A ,s 的面就是 dp[ x2 ][ y2 ], A+B 的面积就是 dp[ x2 ][ y1-1 ],A+C 的面积就是 dp[ x1-1 ][ y2 ], A 的面积就是 dp[ x1-1 ][ y1-1 ] ,所以我们得出(x1,y1)~(x2,y2)这个区间内的数据总和 x = dp[ x2 ][ y2 ] - dp[ x2 ][ y1-1 ] - dp[ x1-1 ][ y2 ] + dp[ x1-1 ][ y1-1 ] 

        上面的两个表达式就是本题的核心了

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

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

相关文章

netty-daxin-3(rpc远程调用)

文章目录 nettyRpcObjectEncoder 与 ObjectDecoderjdk动态代理回顾Rpc调用过程简析服务端客户端 nettyRpc ObjectEncoder 与 ObjectDecoder ObjectEncoder继承自MessageToByteEncoder<Serializable>&#xff0c;它内部使用ByteBufOutputStream包装ByteBuf对象&#xff…

Python 爬虫之简单的爬虫(一)

爬取网页上所有链接 文章目录 爬取网页上所有链接前言一、基本内容二、代码编写1.引入库2.测试网页3.请求网页4.解析网页并保存 三、如何定义请求头&#xff1f;总结 前言 最近也学了点爬虫的东西。今天就先给大家写一个简单的爬虫吧。循序渐进&#xff0c;慢慢来哈哈哈哈哈哈…

TrustGeo代码理解(一)main.py

代码链接:https://github.com/ICDM-UESTC/TrustGeo 一、导入各种模块和数据库 # -*- coding: utf-8 -*- import torch.nnfrom lib.utils import * import argparse, os import numpy as np import random from lib.model import * import copy from thop import profile imp…

devc++如何建立一个c++项目?devc++提示源文件未编译?

打开devc APP后是这样的界面&#xff1b; 点击文件-> 新建->项目&#xff0c;这一点应该不难&#xff0c;主要是最后这个选择什么&#xff1f; 这样即可。 devc提示源文件未编译&#xff1f; 点击工具->编译选项&#xff1b; 如果不能解决&#xff0c;那就是可能路径…

NNDL 循环神经网络-梯度爆炸实验 [HBU]

目录 6.2.1 梯度打印函数 6.2.2 复现梯度爆炸现象 6.2.3 使用梯度截断解决梯度爆炸问题 【思考题】梯度截断解决梯度爆炸问题的原理是什么&#xff1f; 总结 前言&#xff1a; 造成简单循环网络较难建模长程依赖问题的原因有两个&#xff1a;梯度爆炸和梯度消失。 循环…

代码随想录算法训练营第53天| 1143.最长公共子序列 1035.不相交的线 53. 最大子序和 动态规划

JAVA代码编写 1143.最长公共子序列 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情…

软件测试面试八股文(答案解析+视频教程)

1、B/S架构和C/S架构区别 B/S 只需要有操作系统和浏览器就行&#xff0c;可以实现跨平台&#xff0c;客户端零维护&#xff0c;维护成本低&#xff0c;但是个性化能力低&#xff0c;响应速度较慢。 C/S响应速度快&#xff0c;安全性强&#xff0c;一般应用于局域网中&#xf…

【华为数据之道学习笔记】3-10元数据管理架构及策略

元数据管理架构包括产生元数据、采集元数据、注册元数据和运 维元数据。 产生元数据&#xff1a; 制定元数据管理相关流程与规范的落地方案&#xff0c;在IT产品开发过程中实现业务元数据与技术元数据的连接。 采集元数据&#xff1a; 通过统一的元模型从各类IT系统中自动采集元…

Linux下FFmepg使用

1.命令行录一段wav,PCM数据 ffmpeg -f alsa -i hw:0,0 xxx.wav//录制 ffplay out.wav//播放ffmpeg -f alsa -i hw:0,0 -ar 16000 -channels 1 -f s16le 1.pcm ffplay -ar 16000 -channels 1 -f s16le 1.pcm -ar freq 设置音频采样率 -ac channels 设置通道 缺省为1 2.将pcm…

002.Java实现两数相加

题意 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示两数之和的新链表。 示例 输入&#xff1a;l1[2,4,3],l2[5,6,4] 输出…

【从零开始学习JVM | 第七篇】深入了解 堆回收

前言&#xff1a; Java堆作为内存管理中最核心的一部分&#xff0c;承担着对象实例的存储和管理任务。堆内存的高效使用对于保障程序的性能和稳定性至关重要。因此&#xff0c;深入理解Java堆回收的原理、机制和优化策略&#xff0c;对于Java开发人员具有重要的意义。 本文旨在…

springcloud-分布式缓存

文章目录 一.Redis持久化1.RDB持久化2.AOF持久化 二.Redis主从1.搭建主从架构2.全量同步3.增量同步 三.Redis哨兵1.哨兵的作用和原理2.搭建哨兵架构3.RedisTemplate的哨兵模式 四.Redis分片集群1.搭建分片集群2.散列插槽3.集群伸缩4.故障转移5.RedisTemplate访问分片集群 为什么…

树莓派(Raspberry Pi)4B密码忘记了,怎么办?

树莓派长时间不用&#xff0c;导致密码忘记了&#xff0c;这可咋整&#xff1f; 第1步&#xff1a;取出SD卡 将树莓派关机&#xff0c;移除sd卡&#xff0c;使用读卡器&#xff0c;插入到你的电脑。 第2步&#xff1a;编辑 cmdline.txt 在PC上打开SD卡根目录&#xff0c;启动…

Kotlin ArrayList类型toTypedArray转换Array

Kotlin ArrayList类型toTypedArray转换Array data class Point(val x: Float, val y: Float)fun array_test(points: ArrayList<Array<Point>>) {points.forEachIndexed { idx, ap ->ap.forEach {print("$idx $it ")}println()} }fun main(args: Arra…

2697. 字典序最小回文串

2697. 字典序最小回文串 难度: 简单 来源: 每日一题 2023.12.13 给你一个由 小写英文字母 组成的字符串 s &#xff0c;你可以对其执行一些操作。在一步操作中&#xff0c;你可以用其他小写英文字母 替换 s 中的一个字符。 请你执行 尽可能少的操作 &#xff0c;使 s 变…

RTX 40 SUPER发布时间定了!价格也有了

快科技12月16日消息&#xff0c;NVIDIA RTX 40 SUPER系列显卡基本确定将在2024年1月8日正式发布&#xff0c;也就是CES 2024大展期间&#xff0c;随后在1月中下旬陆续解禁上市。 RTX 4070 SUPER 1月16日解禁公版/原价丐版&#xff0c;1月17日解禁高价高配版&#xff0c;上市开…

鸿蒙开发编辑器设置

首先需要知道如何打开设置页面&#xff0c;以下所有设置都需要在设置界面中进行修改&#xff0c;有三种方式可以打开&#xff0c; 1、编辑器左上角file菜单下的Setting菜单。 2、编辑器右上角的设置按钮 3、按快捷键 ctrlalts 注意不要和其他软件案件重复。 一、设置每次打开…

制作一个简单 的maven plugin

流程 首先&#xff0c; 你需要创建一个Maven项目&#xff0c;推荐用idea 创建项目 会自动配置插件 pom.xml文件中添加以下配置&#xff1a; <project> <!-- 项目的基本信息 --> <groupId>com.example</groupId> <artifactId>my-maven-plugi…

腾讯云服务器优惠活动大全页面_全站搜优惠合集

腾讯云推出优惠全站搜页面 https://curl.qcloud.com/PPrF9NFe 在这个页面可以一键查询所需云服务器、轻量应用服务器、数据库、存储、CDN、网络、安全、大数据等云产品优惠活动大全&#xff0c;活动打开如下图&#xff1a; 腾讯云优惠全站搜 腾讯云优惠全站搜页面 txybk.com/go…

springboot笔记

尚硅谷SpringBoot3零基础教程&#xff0c;springboot入门到实战_哔哩哔哩_bilibili SpringBOOT 只会扫描在主程序下的包!!!!!!!!!!!!写在其他包上面会有问题 //SpringBootApplication(scanBasePackages "com") //也可以自己设置扫描路径 &#xff33;&#xff50…