算法体系-19 第十九节 暴力递归到动态规划

一 动画规划的概念 优化出现重复解的递归

一旦写出递归来,改动态规划就很快

尝试策略和状态转移方程是一码事

学会尝试是攻克动态规划最本质的能力

如果你发现你有重复调用的过程,动态规划在算过一次之后把答案记下来,下回在越到重复调用过程就直接调

做题思路 一定要从尝试入手

动态规划的套路从尝试出发,从尝试递归出发,然后在改动态规划的时候第一步找到base的情况填上相应位置的数,然后根据下一步的条件推出其他位置的数;

二 给定四个参数 N、M、K、P,返回方法数,机器人必须走 K 步

2.1描述

假设有排成一行的N个位置,记为1~N,N 一定大于或等于 2

开始时机器人在其中的M位置上(M 一定是 1~N 中的一个)

如果机器人来到1位置,那么下一步只能往右来到2位置;

如果机器人来到N位置,那么下一步只能往左来到 N-1 位置;

如果机器人来到中间位置,那么下一步可以往左走或者往右走;

规定机器人必须走 K 步,最终能来到P位置(P也是1~N中的一个)的方法有多少种

给定四个参数 N、M、K、P,返回方法数。

2.2 分析

2.3 代码

// 机器人当前来到的位置是cur,// 机器人还有rest步需要去走,// 最终的目标是aim,// 有哪些位置?1~N// 返回:机器人从cur出发,走过rest步之后,最终停在aim的方法数,是多少?public static int process1(int cur, int rest, int aim, int N) {if (rest == 0) { // 如果已经不需要走了,走完了!return cur == aim ? 1 : 0;}// (cur, rest)if (cur == 1) { // 1 -> 2return process1(2, rest - 1, aim, N);}// (cur, rest)if (cur == N) { // N-1 <- Nreturn process1(N - 1, rest - 1, aim, N);}// (cur, rest)return process1(cur - 1, rest - 1, aim, N) + process1(cur + 1, rest - 1, aim, N);}

2.4 优化 递归改动态规划 一 有重复解的递归是可以优化的

上面递归的过程中出现了重复的值,采用缓存法记录已经走过的路就不用再走了,一个字问题保证只算一次


public static int ways2(int N, int start, int aim, int K) {if (N < 2 || start < 1 || start > N || aim < 1 || aim > N || K < 1) {return -1;}int[][] dp = new int[N + 1][K + 1];for (int i = 0; i <= N; i++) {for (int j = 0; j <= K; j++) {dp[i][j] = -1;}}// dp就是缓存表// dp[cur][rest] == -1 -> process1(cur, rest)之前没算过!// dp[cur][rest] != -1 -> process1(cur, rest)之前算过!返回值,dp[cur][rest]// N+1 * K+1return process2(start, K, aim, N, dp);}// cur 范: 1 ~ N// rest 范:0 ~ Kpublic static int process2(int cur, int rest, int aim, int N, int[][] dp) {if (dp[cur][rest] != -1) {return dp[cur][rest];}// 之前没算过!int ans = 0;if (rest == 0) {ans = cur == aim ? 1 : 0;} else if (cur == 1) {ans = process2(2, rest - 1, aim, N, dp);} else if (cur == N) {ans = process2(N - 1, rest - 1, aim, N, dp);} else {ans = process2(cur - 1, rest - 1, aim, N, dp) + process2(cur + 1, rest - 1, aim, N, dp);}dp[cur][rest] = ans;return ans;}

三 给定一个整型数组arr,代表数值不同的纸牌排成一条线

范围模型 玩家博弈问题

3.1 描述

给定一个整型数组arr,代表数值不同的纸牌排成一条线

玩家A和玩家B依次拿走每张纸牌

规定玩家A先拿,玩家B后拿

但是每个玩家每次只能拿走最左或最右的纸牌

玩家A和玩家B都绝顶聪明

请返回最后获胜者的分数。

3.2分析

先手

后手,后手能拿的只能是先手拿剩下的

优化1 傻缓存

优化二

3.3代码

package class18;public class Code02_CardsInLine {// 根据规则,返回获胜者的分数public static int win1(int[] arr) {if (arr == null || arr.length == 0) {return 0;}int first = f1(arr, 0, arr.length - 1);int second = g1(arr, 0, arr.length - 1);return Math.max(first, second);}// arr[L..R],先手获得的最好分数返回public static int f1(int[] arr, int L, int R) {if (L == R) {return arr[L];}int p1 = arr[L] + g1(arr, L + 1, R);int p2 = arr[R] + g1(arr, L, R - 1);return Math.max(p1, p2);}// // arr[L..R],这里面是对手做决定,后手获得的最好分数返回public static int g1(int[] arr, int L, int R) {if (L == R) {return 0;}int p1 = f1(arr, L + 1, R); // 对手拿走了L位置的数int p2 = f1(arr, L, R - 1); // 对手拿走了R位置的数return Math.min(p1, p2);}public static int win2(int[] arr) {if (arr == null || arr.length == 0) {return 0;}int N = arr.length;int[][] fmap = new int[N][N];int[][] gmap = new int[N][N];for (int i = 0; i < N; i++) {for (int j = 0; j < N; j++) {fmap[i][j] = -1;gmap[i][j] = -1;}}int first = f2(arr, 0, arr.length - 1, fmap, gmap);int second = g2(arr, 0, arr.length - 1, fmap, gmap);return Math.max(first, second);}// arr[L..R],先手获得的最好分数返回public static int f2(int[] arr, int L, int R, int[][] fmap, int[][] gmap) {if (fmap[L][R] != -1) {return fmap[L][R];}int ans = 0;if (L == R) {ans = arr[L];} else {int p1 = arr[L] + g2(arr, L + 1, R, fmap, gmap);int p2 = arr[R] + g2(arr, L, R - 1, fmap, gmap);ans = Math.max(p1, p2);}fmap[L][R] = ans;return ans;}// // arr[L..R],后手获得的最好分数返回public static int g2(int[] arr, int L, int R, int[][] fmap, int[][] gmap) {if (gmap[L][R] != -1) {return gmap[L][R];}int ans = 0;if (L != R) {int p1 = f2(arr, L + 1, R, fmap, gmap); // 对手拿走了L位置的数int p2 = f2(arr, L, R - 1, fmap, gmap); // 对手拿走了R位置的数ans = Math.min(p1, p2);}gmap[L][R] = ans;return ans;}

3.4 优化代码

 public static int win3(int[] arr) {if (arr == null || arr.length == 0) {return 0;}int N = arr.length;int[][] fmap = new int[N][N];int[][] gmap = new int[N][N];for (int i = 0; i < N; i++) {fmap[i][i] = arr[i];}for (int startCol = 1; startCol < N; startCol++) {int L = 0;int R = startCol;while (R < N) {fmap[L][R] = Math.max(arr[L] + gmap[L + 1][R], arr[R] + gmap[L][R - 1]);gmap[L][R] = Math.min(fmap[L + 1][R], fmap[L][R - 1]);L++;R++;}}return Math.max(fmap[0][N - 1], gmap[0][N - 1]);}public static void main(String[] args) {int[] arr = { 5, 7, 4, 5, 8, 1, 6, 0, 3, 4, 6, 1, 7 };System.out.println(win1(arr));System.out.println(win2(arr));System.out.println(win3(arr));}}

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

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

相关文章

助力全息通信技术!GPS-Gaussian实现2K实时人体新视点合成

论文标题&#xff1a; GPS-Gaussian: Generalizable Pixel-wise 3D Gaussian Splatting for Real-time Human Novel View Synthesis 论文作者&#xff1a; Shunyuan Zheng, Boyao Zhou, Ruizhi Shao, Boning Liu, Shengping Zhang, Liqiang Nie, Yebin Liu 项目地址&#x…

7.无代码爬虫八爪鱼采集器软件——采集规则/项目的创建与网址输入

接上篇 6.零代码网页爬虫软件基础实操——下载与安装八爪鱼采集器 八爪鱼免费爬虫软件下载&#xff1a; 八爪鱼采集器下载 小白数据采集神器​​https://affiliate.bazhuayu.com/retrieve 直接复制粘贴要采集的网站在这里就可以进入采集规则的设计器 自定义任务 通过这个功能…

使用volta管理前端开发环境

背景&#xff1a;公司有新老不同的产品&#xff0c;使用的node版本不一样&#xff0c;每次都要手动切换node版本&#xff0c;对应的项目才能运行。这样很麻烦&#xff0c;有没有好的解决方法&#xff0c;就找到了volta。 1.为什么是volta&#xff1f; 管网介绍&#xff1a;使用…

国内外典型的知识图谱项目

文章目录 早期的知识库项目互联网时代的知识图谱中文开放知识图谱垂直领域知识图谱 从人工智能的概念被提出开始&#xff0c;构建大规模的知识库一直都是人工智能、自然语言理解等领域的核心任务之一。下面分别介绍早期的知识库项目、互联网时代的知识图谱、中文开放知识图谱和…

【论文阅读笔记】PA-SAM: Prompt Adapter SAM for High-Quality Image Segmentation

1.论文介绍 PA-SAM: Prompt Adapter SAM for High-Quality Image Segmentation PA-SAM&#xff1a;用于高质量图像分割的提示适配器SAM 2024年 ICME Paper Code 2.摘要 Segment Anything Model&#xff0c;SAM在各种图像分割任务中表现出了优异的性能。尽管SAM接受了超过10亿…

软考又考了,数据库范式这次一定要弄懂!

0. 引言 今年数据库范式又作为选择题在软考中出题了&#xff0c;范式和反范式同样也在我们日常开发的数据库表设计工作中提供重要理论&#xff0c;今天我们来彻底弄懂几大范式的概念和区别&#xff0c;以及常见的反范式设计方法 1. 定义 1.1 基础概念 在实际讲解之前&#…

终于用上了桌面版本的chatGPT

最近经过不断的探索&#xff0c;也算是用上了桌面版本的chatgGPT&#xff0c;想要用同学&#xff0c;可以关注一下&#xff0c;后面我会出一期教程的&#xff5e;

docker安装elasticsearch8和kibana,带ik分词器

全文目录,一步到位 1.前言简介1.1 专栏传送门 2. elasticsearch和kibana安装2.1 准备工作2.1.1 下载elasticsearch2.1.2 下载kibana镜像 2.2 创建并运行es容器2.2.1 创建es网络2.2.2 创建es容器2.2.3 放行端口2.2.4 访问查看结果> 步骤一: 点击高级, 然后继续访问> 步骤二…

KIVY AliasProperty 运用报错汇总

案例1&#xff1a; 在Kivy中&#xff0c;AliasProperty 允许你创建一个属性的别名&#xff0c;该别名可以基于其他属性计算得到。但是&#xff0c;与普通的Python属性不同&#xff0c;Kivy的Property类&#xff08;包括AliasProperty&#xff09;并没有直接提供定义getter和s…

Tensorflow入门实战 T04-猴痘识别

本篇文章主要&#xff1a;tensorflow 运行环境&#xff1a;本地cpu 运行epoch&#xff1a;50 1、tensorflow官网 tensorflow的官网教程。初学者的 TensorFlow 2.0 教程 | TensorFlow Core 官网上有图像分类的相关详细描述还有代码示例。 2、完整代码展示 from tensorflo…

单调队列总结

单调队列的介绍 由于现在我也没接触过正经的单调队列的定义&#xff0c;因而引申为介绍&#xff0c; 单调队列&#xff0c;类似与单调栈&#xff0c;存储在单调队列里面的元素理应都是单调的&#xff0c;单调队列的基础使用deque&#xff08;双端队列&#xff09;去实现的&am…

【总线】AXI总线:FPGA设计中的通信骨干

目录 AXI4&#xff1a;高性能地址映射通信的基石 AXI4-Lite&#xff1a;轻量级但功能强大的通信接口 AXI4-Stream&#xff1a;高速流数据传输的利器 结语&#xff1a;AXI总线在FPGA设计中的重要性 大家好,欢迎来到今天的总线学习时间!如果你对电子设计、特别是FPGA和SoC设计…

FlowUs息流开启知识管理的新纪元|FlowUs息流公开知识库

在信息爆炸的时代&#xff0c;如何高效地管理和利用知识成为了一个挑战。FlowUs知识库以其超巨的性价比&#xff0c;为用户带来了全新的解决方案。它不仅仅是一个存储信息的工具&#xff0c;更是一个能够激发创造力和提高生产力的平台。 性价比之选 FlowUs以其合理的价格&…

ChromeDriver新手教程:一步步指导Chrome 114到127版本的驱动安装

114之前版本下载链接在这里 ​​​​​​125以后版本下载链接在此&#xff0c;只有后面status是绿色对勾的才可以下载&#xff0c;驱动大版本一致就可以使用&#xff0c;不需版本号一模一样&#xff1b;下载所需版本只需点击对应的版本名称即可跳转到对应版本的下载位置。 以…

学习笔记——网络管理与运维——SNMP(基本配置)

四、SNMP基本配置 1、SNMP配置举例 整个华为数通学习笔记系列中&#xff0c;本人是以网络视频与网络文章的方式自学的&#xff0c;并按自己理解的方式总结了学习笔记&#xff0c;某些笔记段落中可能有部分文字或图片与网络中有雷同&#xff0c;并非抄袭。完处于学习态度&#x…

windows系统把桌面的文件重定向到电脑的其他分区盘

当我们使用windows系统的电脑时&#xff0c;很喜欢把一些常用的文件放到桌面上。而桌面上的文件默认都是设定在C盘下的。时间长了&#xff0c;C盘容易爆红(空间不足)。下面我将介绍一种比较简单快捷的办法来解决这种问题--就是把桌面的文件重定向到电脑的其他分区盘。 首先我们…

[蓝桥杯真题]买二赠一

蓝桥杯真题;买二赠一&#xff0c;要求赠的一价格不能超过买的两者之间最小价格的二分之一 看到这个题的时候我信心满满的一顿操作猛如虎&#xff0c;全部写出来的时候内心想着&#xff0c;稳了&#xff01;这次绝对稳了&#xff01;然而。。。答案错误。。。 我只能去看了一下…

2024年春季学期《算法分析与设计》练习15

问题 A: 简单递归求和 题目描述 使用递归编写一个程序求如下表达式前n项的计算结果&#xff1a; (n<100) 1 - 3 5 - 7 9 - 11 ...... 输入n&#xff0c;输出表达式的计算结果。 输入 多组输入&#xff0c;每组输入一个n&#xff0c;n<100。 输出 输出表达式的计…

使用dev_dbg调试

首先内核要使能两个配置才可以使用。一般内核都是打开的。 CONFIG_DEBUG_FSy CONFIG_DYNAMIC_DEBUGy 当编译选项CONFIG_DYNAMIC_DEBUG打开的时候&#xff0c;在编译阶段&#xff0c;kernel会把所有使用dev_dbg()的信息记录在一个table中&#xff0c;这些信息我们可以从/sys/k…

谷歌发布Infini-Transformer模型—无限注意力机制长度,超越极限

Transformer 是一种基于自注意力机制的深度学习模型&#xff0c;最初应用于自然语言处理领域&#xff0c;现已扩展到图像、音频等多个领域。与传统的循环神经网络 (RNN) 不同&#xff0c;Transformer 不依赖于顺序数据处理&#xff0c;能够并行计算&#xff0c;从而显著提高效率…