当前位置: 首页 > news >正文

暴力递归到动态规划

暴力递归到动态规划

假设有排成一行的n个位置, 记为1~n,n-定大于或等于2。开始时机器人在其中的m位置上(m 一定是1~n中的一个)。如果机器人来到1位置,那么下一步只能往右来到2位置;如果机器人来到n位置, 那么下一步只能往左来到n-1位置;如果机器人来到中间位置,那么下一步可以往左走或者往右走;规定机器人必须走k步,最终能来到p位置(p也是1~n中的一个)的方法有多少种?给定四个参数n、m、k、p,返回方法数。

暴力递归

public static int robot(int n, int m, int k, int p){// 无效参数的情况if (n < 2 || m < 1 || m > n || k < 1 || p < 1 || p > n)return 0;return walk(n, m, k, p);
}// n 还是表示一共n个位置,p 还是表示目标位置
// cur 表示当前位置,rest表示还能走几步
private static int walk(int n, int cur, int rest, int p) {// 如果没有剩余步数了,当前的cur位置就是最后的位置// 如果最后的位置停在P上,那么之前做的移动是有效的// 如果最后的位置没在P上,那么之前做的移动是无效的if (rest == 0)return cur == p ? 1 : 0;if (cur == 1)return walk(n, cur + 1, rest - 1, p);if (cur == n)return walk(n, cur - 1, rest - 1, p);// 如果还有rest步要走,而当前的cur位置在中间位置上,那么当前这步可以走向左,也可以走右// 走向左之后,后续的过程就是,来到cur-1位置 上,还剩rest-1步要走// 走向右之后,后续的过程就是,来到cur+1位置. 上,还剩rest-1步要走// 走向左、走向右是截然不同的方法,所以总方法数要都算上return walk(n, cur - 1, rest - 1, p) + walk(n, cur + 1, rest - 1, p);
}

这种解法是最纯粹的暴力递归,有一些是重复计算。可以发现递归时只有两个参数对结果有实际影响

当前位置 剩余步数 ,如果将这两个参数的取值组成一张矩阵,计算好的数据存在矩阵中,当碰到有重复计算时只需要取值即可。

半动态规划

// 上述的这种暴力递归方法是有重复计算的。可以看出递归中n、p两个参数是固定不变的,结果只取决于(m,k)的组合,如果有
// 一个cache存放各种组合的结果,当重复计算时只需要从cache中返回结果。
public static int robotCache(int n, int m, int k, int p){// 无效参数的情况if (n < 2 || m < 1 || m > n || k < 1 || p < 1 || p > n)return 0;int[][] cache = new int[n + 1][k + 1];// 默认将cache所有元素都设为-1,表示从来没计算过,当递归访问某个元素时发现不是-1时说明已经计算过了,直接取值即可for (int[] ints : cache) Arrays.fill(ints, -1);return walkCache(n, m, k, p, cache);
}// 此时,所有的递归都要带上cache这张表一起玩
private static int walkCache(int n, int cur, int rest, int p, int[][] cache) {if (cache[cur][rest] != -1)return cache[cur][rest];if (rest == 0){cache[cur][rest] = cur == p ? 1 : 0;return cache[cur][rest];}if (cur == 1){cache[cur][rest] = walkCache(n, cur + 1, rest - 1, p, cache);return cache[cur][rest];}if (cur == n){cache[cur][rest] = walkCache(n, cur - 1, rest - 1, p, cache);return cache[cur][rest];}// 在中间位置cache[cur][rest] = walkCache(n, cur - 1, rest - 1, p, cache) +walkCache(n, cur + 1, rest - 1, p, cache);return cache[cur][rest];
}

通过分析发现,当cur=1cur=1cur=1 时,依赖 cache[cur+1][rest−1]cache[cur+1][rest-1]cache[cur+1][rest1] 的值;当 cur=ncur=ncur=n 时,依赖 cache[cur−1][rest−1]cache[cur-1][rest-1]cache[cur1][rest1] 的值;当cur不在首尾时,依赖 cache[cur−1][rest−1]cache[cur-1][rest-1]cache[cur1][rest1]cache[cur+1][rest−1]cache[cur+1][rest-1]cache[cur+1][rest1] 。没有cur=0cur=0cur=0 的情况,虽然cache容量为(N+1)×(K+1)(N+1) \times (K+1)(N+1)×(K+1) ,但那是为了方便运算而已。初始情况下,rest=0rest=0rest=0,如果cur≠pcur \neq pcur=p 则为0,否则为1。假设目标位置p=3p=3p=3 如下图所示:

在这里插入图片描述

如果确定了这种依赖关系后,直接填表就好了,连递归都省了。

纯粹动态规划

public static int dp(int n, int m, int k, int p){// 无效参数的情况if (n < 2 || m < 1 || m > n || k < 1 || p < 1 || p > n)return 0;int[][] cache = new int[n + 1][k + 1];cache[p][0] = 1;// 先填列再填行for (int col = 1; col < cache[0].length; col++) {for (int row = 1; row < cache.length; row++) {if (row == 1)cache[row][col] = cache[row + 1][col - 1];else if (row == cache.length - 1)cache[row][col] = cache[row - 1][col - 1];elsecache[row][col] = cache[row - 1][col - 1] + cache[row + 1][col - 1];}}return cache[m][p];
}

相关文章:

暴力递归到动态规划

暴力递归到动态规划 假设有排成一行的n个位置&#xff0c; 记为1~n&#xff0c;n-定大于或等于2。开始时机器人在其中的m位置上(m 一定是1~n中的一个)。如果机器人来到1位置&#xff0c;那么下一步只能往右来到2位置&#xff1b;如果机器人来到n位置&#xff0c; 那么下一步只能…...

Java:Java仍然处于领先地位?

没有多少编程语言能够自吹自擂并持续流行20多年&#xff0c;但Java就是其中之一。Java应用程序不仅局限于web和移动开发&#xff0c;而且给大数据和人工智能留下了深刻的印象。不用多说&#xff0c;让我们讨论一下Java流行的几个原因!!1.实用性根据JamesGosling的说法&#xff…...

虚拟地址空间

本节目录1.如何理解区域划分2.为什么一个变量可以存储两个不同的值&#xff1f;3.深入理解虚拟地址空间为什么要有地址空间&#xff1f;4.理解什么是挂起&#xff1f;1.虚拟地址空间究竟是什么&#xff1f;2.映射关系的维护是谁做的&#xff1f;1.如何理解区域划分 所谓的区域…...

Python基础篇(十五)-- Pygame游戏编程

1 初识Pygame Pygame是一个开源的Python模块&#xff0c;专门用于多媒体应用&#xff08;如电子游戏&#xff09;的开发&#xff0c;其中包含对图像、声音、视频、事件、碰撞等的支持。Pygame建立在SDL的基础上&#xff0c;SDL是一套跨平台的多媒体开发库&#xff0c;用C语言实…...

LeetCode 热题 HOT 100 Java 题解 -- Part 2

练习地址 Part 1 : https://blog.csdn.net/qq_41080854/article/details/128829494 LeetCode 热题 HOT 100 Java 题解 -- Part 236. 二叉树的中序遍历 9437. 不同的二叉搜索树 9638. 验证二叉搜索树 9839. 对称二叉树 10140. 二叉树的层序遍历 10241. 二叉树的最大深度 10442.…...

【项目实战】IDEA常用快捷键汇总

一、修改为Eclipse的快捷键 相信很多朋友跟我一样&#xff0c; 都是习惯了eclipse的快捷键&#xff0c;没错&#xff0c;习惯这东西真的很难改&#xff01;IDEA非常强大&#xff0c;支持我们修改IDEA中的keymap为Eclipse的快捷键&#xff01;友好又贴心&#xff0c;有没有&…...

更新 TKK 失败,请检查网络连接。谷歌翻译 translation插件不能用解决办法 亲测有效

谷歌翻译无法使用&#xff0c;谷歌回应解释是&#xff0c;谷歌翻译使用率过低&#xff0c;所以选择停止服务。网上也有说法&#xff0c;指出根本原因为&#xff0c;提供API接口的googleapis被墙&#xff0c;这导致js文件和字体资源无法加载。 这里提供两种解决办法 方案一 修…...

SpringBoot整合MybatisPlus多数据源

相信在很多使用MybatisPlus框架的小伙伴都会遇到多数据源的配置问题&#xff0c;并且官网也给出了推荐使用多数据源 (dynamic-datasource-spring-boot-starter) 组件来实现。由于最近项目也在使用这个组件来实现多数据源切换&#xff0c;因此想了解一下该组件是如何运行的&…...

【教程】如何使用Java生成PDF文档?

在如今数字化时代&#xff0c;越来越多的人使用PDF文档进行信息传递和共享。而使用Java生成PDF文档也成为了一个非常重要的技能&#xff0c;因为Java作为一种通用的编程语言&#xff0c;可以在不同的操作系统和平台上运行。下面&#xff0c;我们将为您介绍如何使用Java生成PDF文…...

I.MX6ULL内核开发13:pinctrl子系统和gpio子系统-led实验

目录 一、pinctrl子系统 1.1 pinctrl子系统编写格式以及引脚属性介绍 1.1.1 iomux节点介绍 1.1.2 pinctrl子节点编写格式 1.1.3 引脚配置信息介绍 1.2 将RGB灯引脚添加到pinctrl子系统 1.2.1 查找RGB灯使用的引脚 1.2.2找到引脚宏定义 1.2.3 设置引脚属性 1.2.4 在…...

Linux系列 使用vi文本编辑器

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.vi文本编辑器 1.使用vi文本编辑器 2.vi编辑器的工作模式 3.命令模式中的…...

【java基础】接口(interface)

文章目录基础介绍接口的定义关于接口字段和方法的说明使用接口抽象类和接口接口方法冲突的一些说明方法相同名称和参数&#xff0c;返回值相同方法名称相同&#xff0c;参数不同&#xff0c;返回值相同方法返回值不同&#xff0c;名称参数相同方法完全相同&#xff0c;一个有默…...

ChatGPT(GPT3.5) OpenAI官方API正式发布

OpenAI社区今天凌晨4点多发送的邮件&#xff0c;介绍了ChatGPT官方API的发布。官方介绍文档地址为“OpenAI API”和“OpenAI API”。 ChatGPT(GPT3.5)官方API模型名称为“gpt-3.5-turbo”和“gpt-3.5-turbo-0301”。API调用价格比GPT text-davinci-003模型便宜10倍。调用费用为…...

CAD中如何将图形对象转换为三维实体?

有些小伙伴在CAD绘制完图纸后&#xff0c;想要将图纸中的某些图形对象转换成三维实体&#xff0c;但却不知道该如何操作&#xff0c;其实很简单&#xff0c;本节CAD绘图教程就和小编一起来了解一下浩辰CAD软件中将符合条件的对象转换为三维实体的相关操作步骤吧&#xff01; 将…...

【K8S笔记】Kubernetes 集群架构与组件介绍

K8S 官方文档 https://kubernetes.io/zh/docs/home ##注重关注 概念和任务 板块。 K8S 集群架构 K8S也是运用了分布式集群架构&#xff1a; 管理节点/Master 整个集群的管理&#xff0c;任务协作。工作节点/Node 容器运行、删除。 K8S 组件介绍 管理节点/Master 相关组件 …...

9 怎么登录VNC

1&#xff09;首先在ssh登录后启动vncserver。登陆后输入下面的指令来创建自己的VNC。 命令vncserver :16 –geometry 1900x1000 其中&#xff1a;16是分配的端口号&#xff0c;1900x1000是分辨率。如果没有响应&#xff0c;建议执行下面操作后再次重复上面操作。 命令&#xf…...

MPI ubuntu安装,mpicc,mpicxx,mpif90的区别

介绍 MPI是并行计算的一个支持库&#xff0c;支持对C、C、fortran语言进行并行计算。 安装基础环境 ubuntu进行gcc/g/gfortran的安装&#xff1a; gcc&#xff1a; ubuntu下自带gcc编译器。可以通过gcc -v命令来查看是否安装。 g&#xff1a; sudo apt-get install buil…...

移动端笔记

目录 一、移动端基础 二、视口 三、二倍图/多倍图 四、移动端开发 &#xff08;一&#xff09;开发选择 &#xff08;二&#xff09;常见布局 &#xff08;三&#xff09;移动端技术解决方案 五、移动WEB开发之flex布局 六、移动WEB开发之rem适配布局 #END&#xff08…...

操作系统笔记、面试八股(一)—— 进程、线程、协程

文章目录1. 进程、线程、协程1.1 进程1.1.1 进程间的通信方式1.1.2 进程同步方式1.1.3 进程的调度算法1.1.4 优先级反转1.1.5 进程状态1.1.6 PCB进程控制块1.1.7 进程的创建和撤销过程1.1.8 为什么要有进程1.2 线程1.2.1 为什么要有线程1.2.2 线程间的同步方式1.3 协程1.3.1 什…...

Python每日一练(20230302)

目录 1. 字符串统计 2. 合并两个有序链表 3. 下一个排列 附录 Python字典内置方法 增 删 改 查 其它 1. 字符串统计 从键盘输入一个包含有英文字母、数字、空格和其它字符的字符串&#xff0c;并分别实现下面的功能&#xff1a;统计字符串中出现2次的英文字母&#…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...