蓝桥杯备赛day02 -- 算法训练题 拿金币Java

news2024/10/5 2:27:16

目录

题目:

问题描述

输入格式

输出格式

解题过程

第一步 定义dp数组

第二步 确定 dp 数组递推公式

 第三步 dp数组的初始化

第四步 dp数组的遍历顺序

第五步 举例说明

 报错:内存超限

用dp数组去存储位置上的金币

dp数组从二维降为一维

 收获:


 

题目:

问题描述

  有一个N x N的方格,每一个格子都有一些金币,只要站在格子里就能拿到里面的金币。你站在最左上角的格子里,每次可以从一个格子走到它右边或下边的格子里。请问如何走才能拿到最多的金币。

输入格式

  第一行输入一个正整数n。
  以下n行描述该方格。金币数保证是不超过1000的正整数。

输出格式

  最多能拿金币数量。

样例输入

3
1 3 3
2 2 2
3 1 2

样例输出

11

数据规模和约定

n<=1000


解题过程

这是一道很明显的动态规划问题,那就老规矩动态规划五部曲。

第一步 定义dp数组

采用二维数组dp[ i ][ j ],定义为到第i行第j列时,拿到的最大金币数。

因此在定义数组长度时,需要是(n+1)*(n+1)

(因为数组索引从0开始)

又采用gold[ i ][ j ]数组,存储位置上的金币。

第二步 确定 dp 数组递推公式

我们只能往右走或者往下走,那么到达第i行第j列的位置,只能是从[ i ][ j-1 ]的位置(往右走)或者[ i-1 ][ j ] 的位置(往下走),

那么到[ i ][ j ]拿的金币应该为[ i ][ j-1 ][ i-1 ][ j ] 两者拿金币的最大值 加上[ i ][ j ]位置上的金币。

dp[i][j] = (Math.max(dp[i-1][j], dp[i][j-1]) + gold[i][j]);

 第三步 dp数组的初始化

  • 显然,在起点时,dp[1][1] = gold[1][1]
  • 在第一行时,我们只能往右走,这时dp[ i ][ j ] = dp[ i ][ j-1 ] + gold[ i ][ j ]。                         (注意往右是对 j 的变换,因此是 j-1 )
  • 在第一列时,我们只能往下走,这时dp[ i ][ j ] = dp[ i-1 ][ j ] + gold[ i ][ j ]。                         (注意往下是对i的变换,因此是 i-1 )

第四步 dp数组的遍历顺序

从左上角走到右下角,显然是i++,j++。 

第五步 举例说明

没啥可举例的哈。

最终代码如下,

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[][] dp = new int [n+1][n+1];
        int[][] gold = new int [n+1][n+1];
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++ )
                gold[i][j] = scanner.nextInt();
        dp[1][1] = gold[1][1];
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= n; j++) {
                if(i == 1 && j == 1) dp[i][j] = gold[1][1];
                else if(i == 1) dp[i][j] = dp[i][j-1] + gold[i][j];
                else if(j == 1) dp[i][j] = dp[i-1][j] + gold[i][j];
                else dp[i][j] = (Math.max(dp[i-1][j], dp[i][j-1]) + gold[i][j]);
            }
        }
        System.out.println(dp[n][n]);
    }
}

 报错:内存超限

乐,最终报错了,内存超限。十个评测记录,到第八个走不出来了。


随即就开始想办法优化。

要么将两个数组合并成一个数组,也就是用一开始用dp数组去存储位置上的金币,

要么将dp数组从二维降为一维。

用dp数组去存储位置上的金币

实际上操作跟之前没有什么不同,而且也是可行的。

因为数组是从左到右,从上到下遍历的dp[ i ][ j ] 修改后,就不需要起存储该位置上的金币的作用了,也就是时间错开了一下,从而起到数组有两个作用而不冲突。

代码如下

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[][] dp = new int[n+1][n+1];
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++ )
                dp[i][j] = scanner.nextInt();//用dp数组去存储位置上的金币
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= n; j++) {
                if(i == 1 && j == 1) dp[i][j] = dp[i][j]; 
                else if(i == 1) dp[i][j] = dp[i][j-1] + dp[i][j];
                else if(j == 1) dp[i][j] = dp[i-1][j] + dp[i][j];
                else dp[i][j] = (Math.max(dp[i-1][j], dp[i][j-1]) + dp[i][j]);
            }
        }
        System.out.println(dp[n][n]);
    }
}

dp数组从二维降为一维

  • 关键在于一个理清时间的思维。
  • 初始化时,我们用dp数组去存储第一行各位置,能拿到的最大金币。
  • 在最后一个for循环中,实现了先搜索第i行中的最大金币数,在搜索第i+1行的效果。
    • 两种情况,当j==1时,dp[j] += gold[i][j],意味着上一行中的dp[j],加上位置上的金币数,等于这一行第j列拿到的最大金币数。
    • 否则dp[j] = Math.max(dp[j-1],dp[j]) + gold[i][j]。其中max函数中的dp[j-1]意味着从左边来的,也就是左边位置的最大金币数,与从上边来(上一行)的最大金币数去最大值,加上位置上的金币数。
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[][] gold = new int[n+1][n+1];
        int[] dp = new int [n+1];
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                gold[i][j] = scanner.nextInt();
        //初始化
        for(int j = 1; j <= n; j++) {
            if(j == 1) dp[1] = gold[1][j];
            else dp[j] = dp[j-1] + gold[1][j];
        }
        for(int i = 2; i <= n; i++) {
            for(int j = 1; j <= n; j++) {
                if(j == 1) dp[j] += gold[i][j];
                else dp[j] = Math.max(dp[j-1],dp[j]) + gold[i][j];
            }
        }
        System.out.println(dp[n]);
    }
}

 第二个方法貌似有时候过不了第九个评测样例,然后多测几次就能通过了,不知道是官方系统的问题还是。

 收获:

for(int i = 1; i <= n; i++) 
    for(int j = 1; j <= n; j++ )
        num[i][j] = scanner.nextInt();

实现样例输入,看来java中隔一个空格后就会进行下一个变量的输入。

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

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

相关文章

如何在CentOS 7 中搭建Python 3.0 环境

1、下载 通过https://www.python.org/ftp/python/下载Python安装包&#xff0c;这里下载Python-3.10.9.tgz&#xff1b; 2、上传 借助MobaXterm等工具将Python安装包上传至/opt目录&#xff1b; 3、解压 将JDK压缩文件解压至/opt目录&#xff1a;tar -xvf /opt/Python-3.1…

idea设置编辑器背景颜色

文章目录 一、Ided常用工具栏显示二、更改idea主题设置三、设置代码编辑器背景颜色为豆沙绿四、设置新项目 默认Jdk配置、maven配置1、settings for new projects2、structre for new projects 五、修改代码中注释的字体颜色六、设置编辑器字体大小七、文件编码的设置(可以设置…

【网络安全】【密码学】【北京航空航天大学】实验一、数论基础(上)【C语言和Java实现】

实验一、数论基础&#xff08;上&#xff09; 一、实验目的 1、通过本次实验&#xff0c;熟悉相关的编程环境&#xff0c;为后续的实验做好铺垫&#xff1b; 2、回顾数论学科中的重要基本算法&#xff0c;并加深对其的理解&#xff0c;为本学期密码学理论及实验课程打下良好…

Python - 深夜数据结构与算法之 DP 串讲

目录 一.引言 二.DP 知识点回顾 1.递归 2.分治 3.动态规划 三.DP 经典题目回顾 1.Climb-Stairs [70] 2.Unique-Paths [62] 3.House-Robber [198] 4.Min-Path-Sum [64] 5.Best-Time-Sell-Stock [121] 6.Min-Cost-Climb [746] 7.Edit-Distance [72] 8.Longest-Sub-…

Android PendingIntent 闪退

先来给大家推荐一个我日常会使用到的图片高清处理在线工具&#xff0c;主要是免费&#xff0c;直接白嫖 。 有时候我看到一张图片感觉很不错&#xff0c;但是图片清晰度不合我意&#xff0c;就想有没有什么工具可以处理让其更清晰&#xff0c; 网上随便搜下就能找到&#xff…

C++设计模式(李建忠)笔记1

C设计模式&#xff08;李建忠&#xff09; 本文是学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。 参考链接 Youtube: C设计模式 Gtihub源码与PPT&#xff1a;https://github.com/ZachL1/Bilibili-plus 豆瓣: 设计模式–可复用面向对象软件的基础 文章目录 C设计模…

编译原理1.1习题 语言处理器

图源&#xff1a;文心一言 编译原理习题整理~&#x1f95d;&#x1f95d; 作为初学者的我&#xff0c;这些习题主要用于自我巩固。由于是自学&#xff0c;答案难免有误&#xff0c;非常欢迎各位小伙伴指正与讨论&#xff01;&#x1f44f;&#x1f4a1; 第1版&#xff1a;自…

目标检测-One Stage-YOLOv7

文章目录 前言一、YOLOv7的不同版本二、YOLOv7的网络结构二、YOLOv7的创新点三、创新点的详细解读ELAN和E-ELANBoF训练技巧计划型重参化卷积辅助训练模块标签分配Lead head guided label assignerCoarse-to-fine lead head guided label assigner 基于级联模型的复合缩放方法 总…

开发知识点-JAVA-springboot

springboot springbootConfiguration注解的底层核心原理Bean注解的底层核心原理 springboot Configuration注解的底层核心原理 https://www.bilibili.com/video/BV1rq4y1E7gK/?spm_id_from333.999.0.0&vd_sourcef21773b7086456ae21a58a6cc59023be spring.io 全家桶 24…

【Emgu CV教程】5.4、几何变换之图像翻转

今天讲解的两个函数&#xff0c;可以实现以下样式的翻转。 水平翻转&#xff1a;将图像沿Y轴(图像最左侧垂直边缘)翻转的操作。原始图像中位于左侧的内容将移动到目标图像的右侧&#xff0c;原始图像中位于右侧的内容将移动到目标图像的左侧。垂直翻转&#xff1a;将图像沿X轴…

智能小程序小部件(Widget)导航、地图、画布等组件,以及开放能力、原生组件说明

智能小程序小部件(Widget)导航、地图、画布等组件&#xff0c;以及开放能力、原生组件说明。 导航组件 navigator 页面链接&#xff0c;控制小程序的跳转。navigator 子节点的背景色应为透明色。 属性说明 属性名类型默认值必填说明urlstring是跳转地址deltanumber1否当 …

用Spark在大数据平台DataBricks轻松处理数据

Apache Spark是一个强大的开源分布式计算系统&#xff0c;专为大规模数据处理而设计。而DataBricks则提供了一个基于云的环境&#xff0c;使得在Spark上处理数据变得更加高效和便捷。本文将介绍如何在DataBricks平台上使用Spark轻松处理大数据。DataBricks是一个基于云的大数据…

8.临床预测模型验证——交叉验证/Bootstrap法

基本概念 交叉验证&#xff1a; 将一定比例的数据挑选出来作为训练集&#xff0c;将其余未选中的样本作为测试集&#xff0c;先在训练集中构建模型&#xff0c;再在测试集中做预测。 内部验证&#xff1a;手动将样本随机分为训练集和测试集&#xff0c;先在训练集中构建模型…

MySQL面试题 | 11.精选MySQL面试题

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

vue2 pdfjs-2.8.335-dist pdf文件在线预览功能

1、首先先将 pdfjs-2.8.335-dist 文件夹从网上搜索下载&#xff0c;复制到public文件夹下. 2、在components下新建组件PdfViewer.vue文件 3、在el-upload 中调用 pdf-viewer 组件 4、在el-upload 中的 on-preview方法中加上对应的src路径 internalPreview(file) { //判断需要…

【Python】箱型图和热图绘制详解和示例

箱型图&#xff08;Box Plot&#xff09;和热图&#xff08;Heatmap&#xff09;是两种常用的数据可视化工具&#xff0c;它们各自有着不同的特点和用途。在写总结和文献时对数据的表达更加直观&#xff0c;本文对这两种图像的绘制进行详解和示例。 箱型图由一组数据的最小值、…

中国1981-2023年逐年每15天8km植被指数数据集

摘要 中国1981-2023年逐年每15天8km植被指数数据集来源于GIMMS NDVI数据&#xff0c;包括了1981年7月&#xff0d;2023年12月的长时间序列逐年每15天植被指数变化&#xff0c;格式为arcgis grid格式&#xff0c;投影为WGS84&#xff0c;其时间分辨率是15天&#xff0c;空间分辨…

【机组】算术逻辑运算单元实验的解密与实战

​&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《机组 | 模块单元实验》⏰诗赋清音&#xff1a;云生高巅梦远游&#xff0c; 星光点缀碧海愁。 山川深邃情难晤&#xff0c; 剑气凌云志自修。 ​ 目录 &#x1f33a; 一、 实验目的…

Java NIO (二)NIO Buffer类的重要方法

1 allocate()方法 在使用Buffer实例前&#xff0c;我们需要先获取Buffer子类的实例对象&#xff0c;并且分配内存空间。需要获取一个Buffer实例对象时&#xff0c;并不是使用子类的构造器来创建&#xff0c;而是调用子类的allocate()方法。 public class AllocateTest {static…

3.goLand基础语法

目录 概述语法for常量与变量数组切片 slice切片问题问题1问题2 Make 和 New结构体和指针结构体标签 结束 概述 从 java 转来学 go &#xff0c;在此记录&#xff0c;方便以后翻阅。 语法 for package mainimport "fmt"func main() {for i : 0; i < 3; i {fmt.…