动态规划—机器人移动问题(Java)

😀前言
机器人移动问题是一个经典的动态规划应用场景,它涉及到在给定范围内的位置上进行移动,并计算到达目标位置的方法数。本文将介绍三种解决这一问题的方法:暴力递归、缓存法和动态规划。通过比较不同方法的优缺点,我们将深入理解动态规划在解决问题中的重要性以及如何优化算法以提高性能和空间利用率。

🏠个人主页:尘觉主页

文章目录

  • 动态规划--机器人移动问题(Java)
    • 机器人移动问题
      • 暴力递归
      • 缓存法
      • 动态规划
    • 😄总结

动态规划–机器人移动问题(Java)

机器人移动问题

机器人可在1-N的位置上进行移动,规定三个数据 分别是机器人当前位置 机器人可以移动的步数 机器人的目标位置 计算出机器人用光步数后到达目标位置的方法数

暴力递归

机器人在1-N的范围上进行移动,一共会有3种情况,

在1时,只能右移动

在N时,只能左移动

在中间时,既可以左移,又可以右移;

所以可以根据这几种情况进行暴力递归

递归的终止条件是 当前步数为0 且处于目标位置上

public int moveTimes(int N,int cur,int target,int steps ){//三个参数分别是可以移动的范围 当前位置 目标位置if(steps==0){//如果没有步数了进行返回return cur == target?1:0;}if(cur==1){return moveTimes(N,cur+1,target,steps-1);}if (cur == N){return moveTimes(N,cur-1,target,steps-1);}return moveTimes(N,cur+1,target,steps-1) + moveTimes(N,cur-1,target,steps-1);}

缓存法

通过这种方式我们就可以取得最终的全部可能的情况,但是显然,我们的暴力递归,会多做很对运算。比如当机器人处于中间位置的时,当前的状态是 cur = 5,steps = 10 那么在接下来的递归中我们会有这样的2个分支

​ (4,9)-> (5,8)/ (3,8) | (6,9)-> (5,8)/(7,8)

那么我们的(5,8)在计算过一次之后,还会再次进行计算。这样的情况下,我们的运行时间就会变得过长 。

所以我们引出了傻缓存法,缓存的作用在于,我们进行一次递归的过程中,便将这一次递归的结果记录到缓存中,当下一次再次递归时,可以直接调用之前在缓存中数,进行返回,而不是继续向下递归了,这种方法就是再用时间来换空间!

那么回到这道题,我们的cache就可以用一个二维数组来进行存储,row为我们的当前位置 col 为我们的可移动步数

//傻缓存法public int moveTimes(int N,int cur,int target,int steps,int[][] cache){//cache需要初始化;所有值换成-1;if(cache[cur][steps]!=-1){return cache[cur][steps];}int result = -1;//分3种情况进行递归移动//basecaseif (steps == 0){result = cur == target?1:0;} else if (cur == 1){result = moveTimes(N,cur+1,target,steps-1,cache);} else if(cur == N){result = moveTimes(N,cur-1,target,steps-1,cache);} else{result = moveTimes(N,cur+1,target,steps-1,cache)+moveTimes(N,cur-1,target,steps-1,cache);}cache[cur][steps] = result;return result;}public void setCache(int[][] cache){for (int i = 0; i < cache.length; i++) {for (int j = 0; j < cache[1].length; j++) {cache[i][j] = -1;}}}

这里相比第一种方式会更快一些,但是也是浪费了较大的空间;

动态规划

我们结合一二一起看,会发现我们能basecase的情况发生时,可以在缓存即二维数组中确定一些数,当 step = 0时,在二维数组中这一列,我们除了是目标位置会返回 1 以外,其他位置都会返回 0 。所以我们就可以把确定的数据填写到二维数组中,在看暴力递归的其他情况,当我们在第 1 行的时候 ,只能向右移动,所以我们的返回值,要从相对于二维数组中的当前位置的左下角中的这个元素获取返回值,同理当我们在最后 1 行的时候,那么就应该从当前位置的左上角进行取返回值了,当我们在中间位置的时候,我们的则是需要从左上和左下相加来获取返回值,依次类推,我们会回到我们最开始的位置,这时就是我们需要的结果了。

    public int moveTimes1(int N,int cur,int target,int steps){int[][] cache = new int[N+1][steps+1];//给第一列进行赋值cache[target][0] = 1;for (int i = 1; i <= steps; i++) {//第一行手动操作cache[1][i] = cache[2][i-1];for (int j = 2; j <= N-1 ; j++) {cache[j][i] = cache[j+1][i-1]+cache[j-1][i-1];}cache[N][i] = cache[N-1][i-1];}return cache[cur][steps];}

完整的代码

@SuppressWarnings({"all"})
public class Robot {//测试public static void main(String[] args) {Robot robot = new Robot();int[][] cache = new int[6][6];robot.setCache(cache);System.out.println(robot.moveTimes(5, 2, 3, 5, cache));System.out.println(robot.moveTimes(5,2,3,5));System.out.println(robot.moveTimes1(5,2,3,5));}//动态规划法public int moveTimes1(int N,int cur,int target,int steps){int[][] cache = new int[N+1][steps+1];//给第一列进行赋值cache[target][0] = 1;for (int i = 1; i <= steps; i++) {//第一行手动操作cache[1][i] = cache[2][i-1];for (int j = 2; j <= N-1 ; j++) {cache[j][i] = cache[j+1][i-1]+cache[j-1][i-1];}cache[N][i] = cache[N-1][i-1];}return cache[cur][steps];}//暴力递归法public int moveTimes(int N,int cur,int target,int steps ){//三个参数分别是可以移动的范围 当前位置 目标位置if(steps==0){//如果没有步数了进行返回return cur == target?1:0;}if(cur==1){return moveTimes(N,cur+1,target,steps-1);}if (cur == N){return moveTimes(N,cur-1,target,steps-1);}return moveTimes(N,cur+1,target,steps-1) + moveTimes(N,cur-1,target,steps-1);}//傻缓存法public int moveTimes(int N,int cur,int target,int steps,int[][] cache){//cache需要初始化;所有值换成-1;if(cache[cur][steps]!=-1){return cache[cur][steps];}int result = -1;//分3种情况进行递归移动//basecaseif (steps == 0){result = cur == target?1:0;} else if (cur == 1){result = moveTimes(N,cur+1,target,steps-1,cache);} else if(cur == N){result = moveTimes(N,cur-1,target,steps-1,cache);} else{result = moveTimes(N,cur+1,target,steps-1,cache)+moveTimes(N,cur-1,target,steps-1,cache);}cache[cur][steps] = result;return result;}public void setCache(int[][] cache){for (int i = 0; i < cache.length; i++) {for (int j = 0; j < cache[1].length; j++) {cache[i][j] = -1;}}}
}

😄总结

通过本文的学习,我们了解了三种解决机器人移动问题的方法:暴力递归、缓存法和动态规划。暴力递归虽然简单易懂,但效率低下;缓存法通过牺牲空间来换取时间,提高了效率;而动态规划则利用填充二维数组的方式,避免了重复计算,进一步优化了性能和空间利用率。动态规划在解决各种问题中都有广泛的应用,是一种重要的算法思想。

😁热门专栏推荐
想学习vue的可以看看这个

java基础合集

数据库合集

redis合集

nginx合集

linux合集

手写机制

微服务组件

spring_尘觉

springMVC

mybits

等等等还有许多优秀的合集在主页等着大家的光顾感谢大家的支持

🤔欢迎大家加入我的社区 尘觉社区

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😁
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🍻
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞

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

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

相关文章

11.牛客---链表分割(Java版)

又没找到题目链接 题解: 错误之系列之一 错误之系列之二 代码

MyBatis 解决上篇的参数绑定问题以及XML方式交互

前言 上文:MyBatis 初识简单操作-CSDN博客 上篇文章我们谈到的Spring中如何使用注解对Mysql进行交互 但是我们发现我们返回出来的数据明显有问题 我们发现后面三个字段的信息明显没有展示出来 下面我们来谈谈解决方案 解决方案 这里的原因本质上是因为mysql中和对象中的字段属性…

如何反反爬虫

我们来讲最常见的反反爬虫方法 import requests r requests.get(网页网址) print(r.requests.headers) 一.使用简单的方法把请求头改为真的浏览器模式 import requests link网页地址 heraders{User-Agent:} rrequests.get(link,headersheaders) print(r.requsts.headers)我们…

2024年最受欢迎的 19 个 VS Code 主题排行榜

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

Maven setting配置

<?xml version"1.0" encoding"UTF-8"?> <settings xmlns"http://maven.apache.org/SETTINGS/1.2.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/SETTINGS/1.2.…

Spring Bean 的一生

Spring Bean 的一生包括其从创建到消亡的整个过程&#xff1a; 实例创建 > 填充 > 初始化 > 使用 > 销毁。 这里需要注意的是&#xff0c;从 bean 实例的创建到可以使用之间还包括【填充】和【初始化】两个步骤。 AbstractAutowireCapableBeanFactory::createBean…

GROBID库文献解析

1. 起因 由于某些原因需要在大量的文献中查找相关内容&#xff0c;手动实在是太慢了&#xff0c;所以选择了GROBID库进行文献批量解析 2. GROBID介绍 GROBID是一个机器学习库&#xff0c;用于将PDF等原始文档提取、解析和re-structuring为结构化的XML/TEI编码文档&#xff0…

liblzma/xz漏洞

一、事情概述 在2024年3月28日&#xff0c;研究人员发现在liblzma/xz官方库的5.6.0和5.6.1版本中被发现植入了恶意后门&#xff0c;具体来说&#xff0c;这个后门会篡改Makefile&#xff0c;注入恶意脚本到configure中执行&#xff0c;从而在生成的代码里链接恶意的.o。当满足一…

pytorch yolov5+Deepsort实现目标检测和跟踪+单目测距

最近一直在整理单目测距的内容&#xff0c;想着检测单目测距都写完了&#xff0c;顺手也写个检测跟踪单目测距&#xff0c;算是总结下这部分内容吧&#xff0c;如果有错误&#xff0c;还请不吝赐教&#xff01;&#xff01; 参考文献: YOLOv5DeepSort实现目标跟踪 pytorch yolo…

郭天祥新概念51单片机(第四期读书笔记)

时钟周期、状态周期、机器周期、指令周期与晶振频率之间的关系 1、晶振频率与脉冲的关系 假设单片机的晶振频率是12MHz&#xff0c;那么它的一个脉冲为1/12微秒&#xff1b;晶振单位时间发出的脉冲则为&#xff1a; 12 ∗ 1 0 6 12*10^6 12∗106。 假设单片机的晶振频率是4MH…

Python 音频处理工具库之pydub使用详解

概要 在音频处理领域,Python pydub 库是一个功能强大且易于使用的工具,它可以帮助开发者处理音频文件的各种操作,如剪切、合并、转换格式、调整音量等。本文将详细介绍 pydub 库的功能、用法以及一些实际应用案例,帮助大家更好地了解和使用这个强大的音频处理工具。 什么是…

数据守护者:揭秘备份数据的终极策略

在数字化日益深入的今天&#xff0c;备份数据的重要性不言而喻。无论是个人用户还是企业机构&#xff0c;数据都是最宝贵的资产之一。一旦数据丢失或受损&#xff0c;可能会导致无法挽回的损失&#xff0c;甚至影响业务的正常运转。因此&#xff0c;备份数据成为了一种必要的安…

Linux中查看文件内容的命令

文章目录 一、七类常见的Linux的文件二、显示命令三、分页显示四、显示文件前后内容五、压缩、解压缩六、补充 一、七类常见的Linux的文件 字符文件类型-普通文件&#xff0c;包括纯文本文件、二进制文件、各种压缩文件等。在find命令中&#xff0c;type 选项中用 f来表示d目录…

B站海外商业化探索之路

本期作者 背景 业务背景 B站&#xff08;bilibili&#xff09;出海以来&#xff0c;深耕内容生态和用户播放体验&#xff0c;业务发展逐渐步入正轨&#xff0c;用户体量稳中有升&#xff0c;目前在东南亚视频APP领域占领了一定的市场份额。 如何探索和实施商业化策略&#xff…

搜维尔科技:Manus Prime 3 Mocap数据手套,体验极致的每指触觉!

完全适用于VR虚拟现实场景 特斯拉也在使用的量子数据 Tesla 目前正在使用 MANUS Quantum Metagloves创建一个数据集&#xff0c;帮助他们训练 Tesla 机器人。 量子数据训练QUANTUM AI 我们以类似的方式使用 Quantum Metagloves 来生成一流的手指跟踪数据集&#xff0c;并将其…

GoogleNet神经网络介绍

一、简介 GoogleNet&#xff0c;也称为GoogLeNet&#xff0c;是谷歌工程师设计的一种深度神经网络结构&#xff0c;它在2014年的ImageNet图像识别挑战赛中取得了冠军。该神经网络的设计特点主要体现在其深度和宽度上&#xff0c;通过引入名为Inception的核心子网络结构&#x…

【Linux】05.部署Microsoft SQL Server

通过Docker容器部署MSSQL 拉取镜像 执行以下命令获取镜像&#xff0c;并创建容器 sudo docker run -e "ACCEPT_EULAY" -e "MSSQL_SA_PASSWORD<YourStrongPassw0rd>" \-p 1433:1433 --name mssql --hostname mssql \-d \mcr.microsoft.com/mssql/s…

RWKV_Pytorch:支持多硬件适配的开源大语言模型推理框架

亲爱的技术探索者们&#xff0c;今天我要向大家隆重推荐一个在开源社区中崭露头角的项目——RWKV_Pytorch。这是一个基于Pytorch的RWKV大语言模型推理框架&#xff0c;它不仅具备高效的原生Pytorch实现&#xff0c;而且还扩展了对多种硬件的适配支持&#xff0c;让模型的部署和…

应用方案 | D358 高增益运算放大器,可以用于音频放大器、工业控制、DC 增益部件和所有常规运算放大电路

一、概述 D358 由两个独立的高增益运算放大器组成。可以是单电源工作&#xff0c;也可以是双电源工作&#xff0c;电源低功耗电流与电源电压大小无关。 应用范围包括音频放大器、工业控制、DC 增益部件和所有常规运算放大电路。 D358 采用 DIP8、SOP8、MSOP8 和 TSSOP8 的封装形…

振弦采集仪在地铁工程中的应用与地下结构监测

振弦采集仪在地铁工程中的应用与地下结构监测 随着城市化的快速发展&#xff0c;地铁成为现代城市交通体系的重要组成部分。地铁工程在建设过程中需要进行严格的地下结构监测&#xff0c;以确保施工过程的安全和工程质量的控制。振弦采集仪作为一种先进的监测设备&#xff0c;…