【冲击蓝桥篇】动态规划(上):真题实战+思路解析

news2024/11/17 16:04:41

 🎉🎉欢迎光临🎉🎉

🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀

🌟特别推荐给大家我的最新专栏《数据结构与算法:初学者入门指南》📘📘

希望能和大家一起学习!共同进步!

这是苏泽的个人主页可以看到我其他的内容哦👇👇

努力的苏泽icon-default.png?t=N7T8http://suzee.blog.csdn.net

 本文讲解动态规划! 蓝桥真题实战:数组接龙+蜗牛  

正片

目录

 本文讲解动态规划! 蓝桥真题实战:数组接龙+蜗牛  

2023年蓝桥杯Java组b组I:

题目一:接龙数组

首先,我们定义一个二维数组 dp,其中 dp[i][j] 表示前 i 个接龙数组以数字 j 结尾的最少删除个数。

接下来,我们考虑状态转移方程。对于 dp[i][j],有两种情况:

最后,我们对于最后一位 dp[n-1][i],遍历 i 从 0 到 9,找到其中最小值,即为所求的答案。

我把动态规划的规律总结一下:

那么下一篇我们来看看 另一道蓝桥的真题 蜗牛

我的代码加理解:

思路解析 


2023年蓝桥杯Java组b组I:

题目一:接龙数组


题目描述:
对于一个长度为K的整数数列:A1, A2, ..., AK,我们称之为接龙数列当且仅当Ai的首位数字恰好等于Ai−1的末位数字(2 ≤ i ≤ K)。例如12, 23, 35, 56, 61, 11是接龙数列;12, 23, 34, 56不是接龙数列,因为56的首位数字不等于34的末位数字。所有长度为1的整数数列都是接龙数列。现在给定一个长度为N的数列A1, A2, ..., AN,请你计算最少从中删除多少个数,可以使剩下的序列是接龙序列?

输入格式:
第一行包含一个整数N。
第二行包含N个整数A1, A2, ..., AN。

输出格式:
一个整数代表答案。

样例输入:
5
11 121 22 12 2023

样例输出:
1

提示:
删除22,剩余11, 121, 12, 2023是接龙数列。

最道题咋一看是贪心  实则却是动态规划 

正常情况下 两遍遍历这道题的时间复杂度应该是n方的 但是这样显然无法通过所有测试点  于是 我们使用动态规划的思想  来进行优化这道题

首先,我们定义一个二维数组 dp,其中 dp[i][j] 表示前 i 个接龙数组以数字 j 结尾的最少删除个数。

接下来,我们考虑状态转移方程。对于 dp[i][j],有两种情况:

  1. 如果前 i 个数的末尾数字是 left,末尾数字是 right,那么 dp[i][j] 可以通过删除第 i 个数字或者保留第 i 个数字得到。因此,我们可以得到状态转移方程:dp[i][j] = min(dp[i - 1][left], dp[i][j])
  2. 要么把前 i 个数都删了,要么就是它本身,所以有 dp[i][j] = min(dp[i][j], i)

最后,我们对于最后一位 dp[n-1][i],遍历 i 从 0 到 9,找到其中最小值,即为所求的答案。

int minDeletions = Integer.MAX_VALUE;
        for (int i = 0; i < 10; i++) {
            minDeletions = Math.min(minDeletions, dp[n - 1][i]);
        }

代码:
 

import java.util.Scanner;

public class Solution {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] arr = new int[n];
        for (int i = 0; i < n; i++) {
            arr[i] = scanner.nextInt();
        }
        int result = minDelete(n, arr);
        System.out.println(result);
    }
    
    public static int minDelete(int n, int[] arr) {
        // 定义dp数组
        int[][] dp = new int[n][10];
        for (int i = 0; i < n; i++) {
            dp[i][0] = i;
        }
        for (int j = 1; j <= 9; j++) {
            for (int i = 0; i < n; i++) {
                int left = arr[i] % 10; // 当前数的末尾数字
                int right = arr[i-1] / 10; // 上一个数的首位数字
                if (left == right) {
                    dp[i][j] = Math.min(dp[i-1][left], dp[i][j]);
                }
                dp[i][j] = Math.min(dp[i][j], i);
            }
        }
        // 计算最少删除的个数
        int ans = Integer.MAX_VALUE;
        for (int i = 0; i < n - 1; i++) {
            ans = Math.min(ans, dp[i][0]);
        }
        return ans;
    }
}

动态规划是一种常用的算法设计方法,用于解决一些特定类型的问题。它的核心思想是将问题分解为一系列子问题,并使用记忆化的方法来存储和更新状态信息,从而避免重复计算和时间复杂度的扩张。

我把动态规划的规律总结一下:

  1. 定义状态:首先,我们需要定义问题的状态。状态是描述问题某个特定状态的信息。状态可以是一个数字、一个数组、一个矩阵等,具体取决于问题的性质。状态的选择应该能够包含问题的所有可能情况。

  2. 构建状态转移方程:接下来,我们需要构建状态转移方程,描述如何从一个状态转移到另一个状态。状态转移方程是动态规划问题的核心。它是基于已知的子问题解来计算当前问题解的方法。

  3. 定义初始条件:在应用动态规划时,我们通常需要定义初始条件。初始条件是问题中最简单的情况,它们是解决问题的起点。初始条件的定义应该能够让状态转移方程正确运行。

  4. 计算最终结果:通过迭代计算状态转移方程,我们可以得到问题的最终结果。最终结果是根据问题的定义和要求得出的答案。

那么下一篇我们来看看 另一道蓝桥的真题 蜗牛

题目:

我的代码加理解:

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);

        int n = scan.nextInt();
        int[] x = new int[n + 1]; // 每根杆的横坐标
        int[] origin = new int[n + 1]; // 传送出发点的高度
        int[] dest = new int[n + 1]; // 传送到达点的高度

        // 读入每根杆的横坐标
        for (int i = 1; i <= n; i++) {
            x[i] = scan.nextInt();
        }

        // 读入传送出发点和到达点的高度
        for (int i = 1; i < n; i++) {
            origin[i] = scan.nextInt();
            dest[i + 1] = scan.nextInt();
        }

        // 动态规划dp数组
        double[][] dp = new double[n + 1][2];
        dp[1][0] = dp[1][1] = x[1]; // 第一根杆只能爬过去

        for (int i = 2; i <= n; i++) {
            // 计算去传送出发点的时间,可以从传送到达点出发,也可以从x轴出发
            
            //这里计算的是 如果选择了传送 上一个的到达点 到 本杆的传送点的时间 有两种情况 
            // ①到达点高需要往下走到传送点
            //②传送点高需要往上走到传送点
            double transferTime = origin[i - 1] > dest[i - 1] ? (origin[i - 1] - dest[i - 1]) / 0.7
                    : (dest[i - 1] - origin[i - 1]) / 1.3;

            
            // 这里假设上一杆到当前杆选择了传送的情况  就是两种情况 上上杆要么到达上一杆使用传送要么就走路 
            //①到达上一杆使用的是传送,他并不是从底部往上爬 而是在上上杆传送过来的,那么就要加上 上一到达点到本次传送点的距离(上一步计算的)
            //②到达上一杆使用的是走路 所以要加上从上一杆的底部爬到传送点的时间 也就是到达上一杆的最短时间加上向上爬的时间
            //取最小值
            transferTime = Math.min(dp[i - 1][1] + transferTime, dp[i - 1][0] + origin[i - 1] / 0.7);

            // 到达(X_i,0)所花时间 
            //0意味着他要选择走路 所以在这一条计算中 目标是走到该轮杆子的 底部
            //所以 有两种情况: 
            //①要么是 上一轮杆子选择传送到这个杆子的目标点(这里的时间就是transferTime) 加上从这个传送点上面下来的时间
            //②要么是 上一轮杆子选择走路到这个杆子,所以就是到达上一轮杆子的最短时间加上两杆之间的距离
            dp[i][0] = Math.min(transferTime + dest[i] / 1.3, dp[i - 1][0] + x[i] - x[i - 1]);

            // 到达第i根竹竿上的传送到达点所花时间
            //1意味着在这根杆子上他要选择传送 所以这一条计算的目标是他要走到本杆的传送点
            //那么就有两种情况:
            //①要么上一轮杆子选择了传送,所以就是刚才计算的到达下一杆的传送点的时间 
            //②要么上一轮杆子选择了走路,所以就是到达上一轮杆子的最短时间加上上爬到传送点的时间
            dp[i][1] = Math.min(transferTime, dp[i][0] + dest[i] / 0.7);
        }

        // 保留两位小数输出结果,即dp[n][0]
        System.out.println(String.format("%.2f", dp[n][0]));
    }
}

思路解析 

首先,读入输入数据,包括竹竿的数量n,每根竹竿的横坐标x,以及传送出发点和到达点的高度origin和dest。

接下来,定义一个二维数组dp,用于存储状态转移的结果。dp[i][j]表示蜗牛到达第i根竹竿的状态,其中j=0表示蜗牛在竹竿上爬行,j=1表示蜗牛选择传送到达。

然后,对于第一根竹竿,蜗牛只能选择在x轴上爬行,所以dp[1][0]和dp[1][1]都等于x[1],即第一根竹竿的横坐标。

接下来,从第2根竹竿开始进行动态规划。对于每根竹竿,计算到达该竹竿的最短时间。

首先,计算蜗牛从上一根竹竿传送到达该竹竿的时间。这里有两种情况:如果传送点高度高于上一根竹竿的到达点高度,蜗牛需要爬下来,所以时间为(传送点高度-到达点高度)/0.7;如果传送点高度低于上一根竹竿的到达点高度,蜗牛需要爬上去,所以时间为(到达点高度-传送点高度)/1.3。取两种情况中的最小值。

然后,计算蜗牛到达该竹竿底部的时间。这里也有两种情况:如果上一根竹竿选择传送到达该竹竿的目标点,那么时间为传送时间加上从传送点爬下来的时间;如果上一根竹竿选择在x轴上爬行到达该竹竿,那么时间为上一根竹竿的最短时间加上两根竹竿之间的距离。取两种情况中的最小值。

最后,输出结果,保留两位小数。

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

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

相关文章

普中51单片机学习(EEPROM)

EEPROM IIC串行总线的组成及工作原理 I2C总线的数据传送 数据位的有效性规定 I2C总线进行数据传送时&#xff0c;时钟信号为高电平期间&#xff0c;数据线上的数据必须保持稳定&#xff0c;只有在时钟线上的信号为低电平期间&#xff0c;数据线上的高电平或低电平状态才允许…

【Java 基础】Java 数组、方法极致精讲

《Java 零基础入门到精通》专栏持续更新中。通过本专栏你将学习到 Java 从入门到进阶再到实战的全套完整内容,所有内容均将集中于此专栏。无论是初学者还是有经验的开发人员,都可从本专栏获益。 订阅专栏后添加我微信或者进交流群,进群可找我领取 前端/Java/大数据/Python/低…

从0到1使用C++实现一个模拟器-1-【实现最简CPU】

文章目录 uint64_tstdstd::arrayCPU和CU类构造函数size_tstatic_caststd::ifstreamriscv64-unknown-elf-objcopy -O binary add-addi add-addi.binriscv64-unknown-elf-gcc -Wl,-Ttext0x0 -nostdlib -o add-addi add-addi.s-wlstd::hex std::setw() std::setfill()各自的用法he…

upload-Labs靶场“1-5”关通关教程

君衍. 一、环境搭建二、第一关 前端JS检测后缀1、源码分析2、禁用浏览器JS上传3、burp抓包修改 三、第二关 MIME头验证1、源码分析2、burp抓包绕过 四、第三关 PHP3绕过1、源码分析2、PHP3绕过 五、第四关 .htaccess重写绕过1、源码分析2、.htaccess复写 六、第五关 黑名单大小…

Qt槽函数不响应的原因总结

Qt专栏&#xff1a;http://t.csdnimg.cn/LE2Lx 目录 1.问题 2.原因 2.1.没有继承QObject&#xff0c;声明Q_OBJECT宏 2.2.信号槽参数不匹配 2.3.信号函数未声明为 signals 2.4.访问权限 2.5.注意connect的位置&#xff0c;信号在创建信号槽连接前使用&#xff0c;则无法…

C#使用iText7将多个PDF文档合并为单个文档

使用HtmlAgilityPack抓取并分析网页内容&#xff0c;然后再调用PuppeteerSharp将网页生成PDF文件&#xff0c;最终的成果如下图所示&#xff0c;得到将近120个pdf文档。能看&#xff0c;但是不方便&#xff0c;需要逐个打开文档才能看到所需的内容&#xff0c;最好能将这些文档…

java 企业培训管理系统Myeclipse开发mysql数据库web结构jsp编程计算机网页项目

一、源码特点 java 企业培训管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0&…

Vulnhub靶机:basic_pentesting_2

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;10.0.2.4&#xff09; 靶机&#xff1a;basic_pentesting_2&#xff08;10.0.2.7&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://download.vulnhub.c…

未来已来:智慧餐饮点餐系统引领餐饮业的数字化转型

时下&#xff0c;智慧餐饮点餐系统正在引领着餐饮业迈向更高的位置。今天&#xff0c;小编将与大家共同探讨智慧餐饮点餐系统的发展趋势、优势以及对餐饮业的影响。 一、智慧餐饮点餐系统的发展趋势 智慧餐饮点餐系统的出现填补了这一空白&#xff0c;它通过引入数字化技术&a…

基于springboot+vue的医院资源管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

IDEA-DeBug理论与实践

文章目录 01_Debug简介和意义02_IDEA中的Debug步骤03_跳转到当前代码执行的行04_步过调试的使用05_步入调试的使用06_强制步入调试的使用07_步出调试的使用08_回退断点调试的使用09_运行到光标处10_计算表达式11_条件断点12_多线程调试 在软件开发中&#xff0c;IDEA&#xff0…

让燃油车再次破防 比亚迪汉唐荣耀双出击

相信很多读者朋友都还记得&#xff0c;就在不久前趣味科技曾经报道&#xff0c;2024龙年伊始比亚迪就打着“电比油低”的旗号&#xff0c;推出了价格仅为7.98万元起的秦PLUS、驱逐舰05荣耀版&#xff0c;向合资燃油车发起了大举进攻。 这两款“7”字头售价的车型上市&#xff0…

<网络安全>《60 概念讲解<第七课 网络模型OSI对应协议>》

1 OSI模型 OSI模型&#xff08;Open Systems Interconnection Model&#xff09;是一个由国际标准化组织&#xff08;ISO&#xff09;提出的概念模型&#xff0c;用于描述和标准化电信或计算系统的通信功能&#xff0c;以实现不同通信系统之间的互操作性。该模型将通信系统划分…

智能驾驶规划控制理论学习-基于采样的规划方法

目录 一、基于采样的规划方法概述 二、概率路图&#xff08;PRM&#xff09; 1、核心思想 2、实现流程 3、算法描述 4、节点连接处理 5、总结 三、快速搜索随机树&#xff08;RRT&#xff09; 1、核心思想 2、实现流程 3、总结 4、改进RRT算法 ①快速搜索随机图&a…

每日一类:QString类深入讲解

QString类是Qt框架中的一个核心组件&#xff0c;设计用于方便、高效地处理Unicode字符串。与标准C中的字符串处理方式相比&#xff0c;QString提供了更为丰富的API&#xff0c;支持国际化&#xff0c;并且内部使用UTF-16编码&#xff0c;能够处理世界上几乎所有的语言文字。 设…

Python图像形态学处理:腐蚀、膨胀、礼帽、黑帽……

文章目录 二值形态学灰度形态学 python图像处理教程&#xff1a;初步&#x1f4f7;插值变换 最基础的形态学操作有四个&#xff0c;分别是腐蚀、膨胀、开计算和闭计算&#xff0c;【scipy.ndimage】分别实现了二值数组和灰度数组的这四种运算。而针对灰度图像&#xff0c;【sc…

android路由表APP,携程Android面试题

大家应该看过很多分享面试成功的经验&#xff0c;但根据幸存者偏差的理论&#xff0c;也许多看看别人面试失败在哪里&#xff0c;对自己才更有帮助。 最近跟一个朋友聊天&#xff0c;他准备了几个月&#xff0c;刚刚参加完字节跳动面试&#xff0c;第二面结束后&#xff0c;嗯&…

(案例贴2) html+css 倒计时器

欢迎大家使用这个计时器噢 老哥直接附代码咯. timer.html <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0">&l…

python 小游戏《2048》字符版非图形界面

参考链接&#xff1a; 闲谈2048小游戏和数组的旋转及翻转和转置 目录 2048 一、方阵类 二、随机插入1或2 三、 合并和递增 四、 判断和移动 五、 键盘控制 完整源代码 玩法过程 2048 上回说到2048小游戏中数组的各种旋转、翻转的方法&#xff0c;就是为代码编程作准…

非阻塞实现高效键盘扫描功能(STM32F4XX)

目录 概述 1 原理分析 1.1 技术背景 1.2 系统硬件 1.3 STM32 IO&#xff08;输入模式&#xff09;寄存器分析 1.3.1 输入IO的功能描述 1.3.2 输入配置 1.3.3 GPIO 寄存器&#xff08;输入模式相关&#xff09; 1.3.3.1 GPIO 端口模式寄存器 1.3.3.2 GPIO 端口上拉/下拉…