算法体系-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,一经查实,立即删除!

相关文章

MySQL中的隐式转换(Implicit Conversion)

MySQL中的隐式转换&#xff08;Implicit Conversion&#xff09;指的是在SQL语句的执行过程中&#xff0c;数据库管理系统&#xff08;DBMS&#xff09;自动进行的数据类型转换。这种转换通常发生在数据类型不匹配但需要进行比较、计算或赋值等操作时。 以下是一些关于MySQL隐…

助力全息通信技术!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…

vscode不能进行go跳转

辗转反侧&#xff0c;弄了好久好久终于出山了 总结&#xff1a;跟vscode版本插件有关 老版本vscode DocsTool修改成godoc 新版本vscode go get golang.org/x/tools/goplslatest setting中 "go.useLanguageServer": true, "[go]": {"editor.snipp…

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

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

移动端浏览器调试工具vconsole

方案一&#xff1a;通过CDN地址引入 步骤一&#xff1a;通过CDN地址引入 <script src"https://cdn.bootcss.com/vConsole/3.2.2/vconsole.min.js"></script> 步骤二&#xff1a;实例化 <script> var vConsole new VConsole(); </script&g…

WebSocket——学习

WebSocket WebSocket 的基本概念什么是 WebSocket&#xff1f;WebSocket 的优点 WebSocket 的工作原理握手过程数据传输 WebSocket APIJavaScript WebSocket API WebSocket 服务器端实现使用 Java 实现 WebSocket 服务器使用 Netty 实现 WebSocket 服务器 WebSocket 应用场景总…

力学中应变的度量01——我好几年的疑惑终于有解了

文章目录 0、背景描述1、拉伸比&#xff08;率&#xff09; λ \lambda λ2、应变的引入3、一维应变概念的拓展4 总结 0、背景描述 在学校里的时候&#xff0c;我就一直很好奇应变的定义为何如此花里胡哨、五花八门&#xff0c;各种教材又都只是定义&#xff0c;从来不解释究竟…

Kylin V10 Server 下TongRDS独立哨兵服务配置手册

一、网络架构设计 部署类型 目录 IP Port 中心节点 /opt/rds/pcenter 10.8.3.34 6300 服务节点 /opt/rds/pmemedb 10.8.3.35 TongRDS 协议端口:6200 Redis 仿真端口:6379 哨兵监听端口:26379 10.8.3.36 二、部署服务节点 1.查看操作系统信息 [root@localhost ~]# cat /etc/.…

代码随想录算法训练营Day41|背包问题、分割等和子集

背包问题 二维 46. 携带研究材料&#xff08;第六期模拟笔试&#xff09; (kamacoder.com) dp数组有两维&#xff0c;横轴表示背包重量j&#xff08;0-j&#xff09;&#xff0c;纵轴表示不同物品&#xff08;0-i&#xff09;&#xff0c;dp[i][j]即表示从下标为[0-i]的物品…

使用volta管理前端开发环境

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

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

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

MYSQL 字母大小转换

1、UCASE() 解释&#xff1a;把数值列(字段)的字每母转换为大写。 语法格式&#xff1a;SELECT UCASE(column_name) FROM table_name 中文注释&#xff1a;select UCASE(数值列/字段) from 表名 ; 用法&#xff1a; SELECT UCASE(column_name) FROM table_name;2、LCASE(…

【论文阅读笔记】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亿…

# Mac环境如何安装Flutter:全面指南

Mac环境如何安装Flutter&#xff1a;全面指南 Flutter 是 Google 开发的开源移动 UI 框架&#xff0c;允许开发者使用 Dart 语言快速在 iOS 和 Android 上构建高质量的原生界面。本指南将详细指导您如何在 Mac 环境下安装 Flutter&#xff0c;确保您能够顺利开始 Flutter 开发…

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

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

Python实现连连看12

4.2.5 获取图片连接方式 通过自定义函数getLinkType()获取图片的连接方式,代码如下所示。 def getLinkType(pre_row, pre_col, cur_row, cur_col):if pics_map[pre_row][pre_col] != pics_map[cur_row][cur_col]:return NONE_LINKif isNoCornerLink(pre_row, pre_col, cur_r…

嵌入式数据库_3.嵌入式数据库的主要功能及典型产品

1.嵌入式数据库的功能 嵌入式数据库的功能应与通用数据库功能相似&#xff0c;应覆盖数据库的核心功能。通常&#xff0c;嵌入式数据库有其自身的特殊需要&#xff0c;它应具备的功能包括以下4点&#xff1a; 足够高效的数据存储机制&#xff1b;数据安全控制&#xff08;锁机…

终于用上了桌面版本的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 访问查看结果> 步骤一: 点击高级, 然后继续访问> 步骤二…

力扣878.第N个神奇数字

力扣878.第N个神奇数字 二分答案 check()&#xff1a;公共部分为最大公倍数的倍数 class Solution {const long MOD 1e9 7;public:int nthMagicalNumber(int n, int a, int b) {//lcm函数 求最大公倍数long lcm std::lcm(a,b);auto check [&](long long mid) -> …