动态规划—机器人移动问题(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连支持一下,创造不易您们的支持是我的动力🤞
相关文章:
动态规划—机器人移动问题(Java)
😀前言 机器人移动问题是一个经典的动态规划应用场景,它涉及到在给定范围内的位置上进行移动,并计算到达目标位置的方法数。本文将介绍三种解决这一问题的方法:暴力递归、缓存法和动态规划。通过比较不同方法的优缺点,…...

第十一届蓝桥杯物联网试题(省赛)
对于通信方面,还是终端A、B都保持接收状态,当要发送的数组不为空再发送数据,发送完后立即清除,接收数据的数组不为空则处理,处理完后立即清除,分工明确 继电器不亮一般可能是电压不够 将数据加空格再加\r…...

【Python基础教程】5. 数
🎈个人主页:豌豆射手^ 🎉欢迎 👍点赞✍评论⭐收藏 🤗收录专栏:python基础教程 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、…...

Qt中出现中文乱码的原因以及解决方法
Qt专栏:http://t.csdnimg.cn/C2SDN 目录 1.引言 2.原因分析 3.源文件的编码格式修改方法 4.程序内部使用的默认编码格式修改方法 5.QString转std::string的方法 6.总结 1.引言 在编写Qt程序的时候,或多或少都可能遇到用QString时候,明明…...

Linux 文件相关命令
一、查看文件命令 1)浏览文件less 默认查看文件的前 10 行。 less /etc/services ##功能说明: #1.默认打开首屏内容 #2.按【回车】按行访问 #3.按【空格】按屏访问 #4.【从上向下】搜索用/111,搜索包含111的内容,此时按n继续向下搜&#x…...
K8S Deployment 简介, 1个简单的Kubernetes Deployment YAML 文件
当谈到 Kubernetes 集群中的应用程序部署和管理时,Deployment、ReplicaSet 和 Pod 是三个重要的概念。它们之间存在一定的关系和层次结构。下面是对 Deployment、ReplicaSet 和 Pod 的详细解释以及它们之间的关系。 Deployment(部署) Deploy…...

win11安装WSL UbuntuTLS
win11安装WSL WSL 简介WSL 1 VS WSL 2先决要求安装方法一键安装通过「控制面板」安装 WSL 基本命令Linux发行版安装Ubuntu初始化相关设置root用户密码网络工具安装安装1panel面板指导 WSl可视化工具问题总结WSL更新命令错误Ubuntu 启动初始化错误未解决问题 WSL 简介 Windows …...
第十题:金币
题目描述 国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到…...
Windows 11 中Docker的安装教程
选择正确的Docker版本 在Windows上,你可以安装两种类型的Docker:Docker Desktop和Docker Toolbox。Docker Desktop是针对Windows 10 Pro、Enterprise和Education版本的,这些版本内置了Hyper-V虚拟化支持。对于旧版本的Windows,比…...

纯C代码模板
一、快排 void QuickSort(int *a,int left,int right){if(left>right) return;else{int low left,high right;int pivot a[low];while(low<high){while(a[high] > pivot && low < high){high--;}a[low] a[high]; //必须先动a[low]while(a[low] < …...

二、GitLab相关操作
GitLab相关操作 一、组、用户、项目管理1.创建组2.创建项目3.创建用户并分配组3.1 创建用户3.2 设置密码3.3 给用户分配组 二、拉取/推送代码1.配置ssh(第一次需要)1.1 创建一个空文件夹1.2 配置本地仓账号和邮箱1.3 生成ssh公钥密钥1.4 gitlab配置公钥 2.拉取代码3.推送代码3.…...
【详细注释+流程讲解】基于深度学习的文本分类 TextCNN
前言 这篇文章用于记录阿里天池 NLP 入门赛,详细讲解了整个数据处理流程,以及如何从零构建一个模型,适合新手入门。 赛题以新闻数据为赛题数据,数据集报名后可见并可下载。赛题数据为新闻文本,并按照字符级别进行匿名…...
Day.21
interface MyInterface{public final static int PI 3;void show();public default void printX(){System.out.println("接口默认方法");}public static void printY(){System.out.println("接口静态方法");}}class MyClass implements MyInterface{publi…...

Spring-IoC 基于注解
基于xml方法见:http://t.csdnimg.cn/dir8j 注解是代码中的一种特殊标记,可以在编译、类加载和运行时被读取,执行相应的处理,简化 Spring的 XML配置。 格式:注解(属性1"属性值1",...) 可以加在类上…...

Spring声明式事务以及事务传播行为
Spring声明式事务以及事务传播行为 Spring声明式事务1.编程式事务2.使用AOP改造编程式事务3.Spring声明式事务 事务传播行为 如果对数据库事务不太熟悉,可以阅读上一篇博客简单回顾一下:MySQL事务以及并发访问隔离级别 Spring声明式事务 事务一般添加到…...
【C语言数据库】Sqlite3基础介绍
1. SQLite简介 SQLite is a C-language library that implements a small, fast, self-contained, high-reliability, full-featured, SQL database engine. SQLite is the most used database engine in the world. SQLite is built into all mobile phones and most computer…...

el-upload上传图片图片、el-load默认图片重新上传、el-upload初始化图片、el-upload编辑时回显图片
问题 我用el-upload上传图片,再上一篇文章已经解决了,el-upload上传图片给SpringBoot后端,但是又发现了新的问题,果然bug是一个个的冒出来的。新的问题是el-upload编辑时回显图片的保存。 问题描述:回显图片需要将默认的 file-lis…...
【拓扑空间】示例及详解1
例1 度量空间的任意两球形邻域的交集是若干球形邻域的并集 Proof: 任取空间的两个球形邻域、,令 任取,令 球形领域 例2 规定X的子集族,证明是X上的一个拓扑 Proof: 1. 2., (若干个球形邻域的并集都是的元素,元素…...

linux安装jdk8
上传到某个目录,例如:/usr/local/ tar -xvf jdk-8u144-linux-x64.tar.gz配置环境变量: export JAVA_HOME/usr/local/java export PATH$PATH:$JAVA_HOME/bin设置环境变量: source /etc/profile...

Spring重点知识(个人整理笔记)
目录 1. 为什么要使用 spring? 2. 解释一下什么是 Aop? 3. AOP有哪些实现方式? 4. Spring AOP的实现原理 5. JDK动态代理和CGLIB动态代理的区别? 6. 解释一下什么是 ioc? 7. spring 有哪些主要模块?…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...

网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...

376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...