<蓝桥杯软件赛>零基础备赛20周--第18周--动态规划初步
报名明年4月蓝桥杯软件赛的同学们,如果你是大一零基础,目前懵懂中,不知该怎么办,可以看看本博客系列:备赛20周合集
20周的完整安排请点击:20周计划
每周发1个博客,共20周。
在QQ群上交流答疑:
文章目录
- 1. 动态规划的概念
- 2. 动态规划的两种编码方法
- 3. DP设计基础
- 4. 常见线性DP
- 5. DP习题
第18周: 动态规划初步
动态规划(Dynamic Programming,DP)是Richard Bellman于1950年代发明的应用于多阶段决策的数学方法。和贪心、分治一样,动态规划是一种解题的思路,而不是一个具体的算法知识点。动态规划是地地道道的“计算思维”,非常适合用计算机实现,可以说是独属于计算机学科的计算理论。动态规划是一种需要学习才能获得的思维方法。像贪心、分治这样的方法,在生活中,或在其他学科中有很多类似的例子,很容易联想和理解。但动态规划不是,它是一种生活中没有的抽象计算方法,没有学过的人很难自发产生这种思路。
DP是算法竞赛中最常见的考点之一,蓝桥杯大赛的每一场比赛,每次必有DP题目,少则一题,多则数题。以2023年第十四届蓝桥杯省赛为例,
C/C++:A组“更小的数”、B组“接龙数列”、C组“填充”、研究生组“奇怪的数”。
Java:A组“高塔”、B组“ 数组分割,蜗牛,合并石子”、C组“填充”、研究生组“奇怪的数”。
Python:A组“奇怪的数”、B组“松散子序列,保险箱,树上选点”、C组“填充,奇怪的数”、研究生组“填充,高塔”。
能做DP题目,就有蓝桥杯省赛二等奖的实力。
1. 动态规划的概念
本节以斐波那契数为例说明DP的概念和编程实现。
斐波那契数列是一个递推数列,前几个数是1、1、2、3、5、8,第n个数等于第n-1个和第n-2个相加。斐波那契数的递推公式是:
fib(n) = fib(n-1) + fib(n-2)
斐波那契数列又称为兔子数列。设一对兔子每月能生一对小兔子,小兔子在出生的第一个月没有生殖能力,第二个月便能生育,且所有兔子都不会死亡。从第一对刚出生的兔子开始,问12个月以后会有多少对兔子。
斐波那契数列也常常用楼梯问题来举例。一次可以走一个台阶或者两个台阶,问走到第n个台阶时,一共有多少种走法?要走到第n级台阶,分成两种情况,一种是从n-1级台阶走一步过来,一种是从n-2级台阶走两步过来。这就是斐波那契数列的递推公式。
计算斐波那契数列,可以直接用递推公式计算。这里为了说明动态规划的思想,用递归来求斐波那契数,代码如下。
int fib (int n){if (n == 1 || n == 2) return 1;return (fib (n-1) + fib (n-2)); //递归以2的倍数增加
}
为了解决总体问题fib(n),将其分解为两个较小的子问题fib(n-1)和fib(n-2),这就是DP的应用场景。
有一些问题有两个特征:重叠子问题、最优子结构。用DP可以高效率地处理具有这2个特征的问题。
(1)重叠子问题
首先,子问题是原大问题的小版本,计算步骤完全一样;其次,计算大问题的时候,需要多次重复计算小问题。这就是“重叠子问题”。以斐波那契数为例,用递归计算fib(5),分解为图示的子问题。
图1 计算斐波那契数
其中fib(3)计算了2次,其实只算1次就够了。
一个子问题的多次重复计算,耗费了大量时间。用DP处理重叠子问题,每个子问题只需要计算一次,从而避免了重复计算,这就是DP效率高的原因。
(2)最优子结构
最优子结构的意思是:首先,大问题的最优解包含小问题的最优解;其次,可以通过小问题的最优解推导出大问题的最优解。在斐波那契问题中,把数列的计算构造成fib(n) = fib(n-1) + fib(n-2),即把原来为n的大问题,减小为n-1和n-2的小问题,这是斐波那契数的最优子结构。
2. 动态规划的两种编码方法
处理DP中的大问题和小问题,有两种思路:自顶向下(Top-Down,先大问题再小问题)、自下而上(Bottom-Up,先小问题再大问题)。
编码实现DP时,自顶向下用带记忆化搜索的递归编码,自下而上用递推编码。两种方法的复杂度是一样的,每个子问题都计算一遍,而且只计算一遍。
(1)自顶向下与记忆化
先考虑大问题,再缩小到小问题,递归很直接地体现了这种思路。为避免递归时重复计算子问题,可以在子问题得到解决时,就保存结果,再次需要这个结果时,直接返回保存的结果就行了。这种存储已经解决的子问题的结果的技术称为“记忆化(Memoization)”。
以斐波那契数为例,记忆化代码如下:
int memoize[N]; //保存结果
int fib (int n){if (n == 1 || n == 2) return 1;if(memoize[n] != 0) return memoize[n]; //直接返回保存的结果,不再递归memoize[n]= fib (n - 1) + fib (n - 2); //递归计算结果,并记忆return memoize[n];
}
在这个代码中,一个斐波那契数只计算一次,所以总复杂度是O(n)的。
(2)自下而上与制表递推
这种方法与递归的自顶向下相反。这种“自下而上”的方法,先解决子问题,再递推到大问题。通常通过填写表格来完成,编码时用若干for循环语句填表。根据表中的结果,逐步计算出大问题的解决方案。
用制表法计算斐波那契数,维护一个一维表dp[],记录自下而上的计算结果,更大的数是前面两个数的和。
代码:
const int N = 255;
int dp[N];
int fib (int n){dp[1] = dp[2] =1;for (int i=3;i<=n;i++) dp[i] = dp[i-1] +dp[i-2];return dp[n];
}
把表格dp[]称为DP状态,dp[]的转移方程是dp[i] = dp[i-1] +dp[i-2]。
代码的复杂度显然也是O(n)的。
对比“自顶向下”和“自下而上”这两种方法,“自顶向下”的优点是能更宏观地把握问题、认识问题的实质,“自下而上”的优点是编码更直接。两种编码方法都很常见。
能用DP求解的问题,一般是求方案数,或者求最值。
3. DP设计基础
用下面的例子讲解DP的基本问题:状态设计、状态转移、编码实现。
更小的数 2023年第十四届省赛C/C++大学A组,10分
【题目描述】 有一个长度均为n且仅由数字字符0 ~ 9组成的字符串,下标从0到n-1。你可以将其视作是一个具有n位的十进制数字num。小蓝可以从num中选出一段连续的子串并将子串进行反转,最多反转一次。小蓝想要将选出的子串进行反转后再放入原位置处得到的新的数字numnew满足条件numnew < num。请你帮他计算下一共有多少种不同的子串选择方案。只要两个子串在num中的位置不完全相同我们就视作是不同的方案。注意,我们允许前导零的存在,即数字的最高位可以是0,这是合法的。
【输入描述】输入一行包含一个长度为n的字符串表示num(仅包含数字字符0 ∼9),从左至右下标依次为 0 ∼n−1。对于20%的评测用例,1≤n≤100;对于40%的评测用例,1≤n≤1000;对于所有评测用例,1≤n≤5000。
【输出描述】输出一个整数表示答案。
输入样例:
210102 输出样例:
8
如果读者没学过动态规划,也能用模拟法做这一题。遍历出每个子串,判断这个子串反转后是否合法,也就是判断是否有numnew < num。统计所有合法的情况,就是答案。代码很容易写。
#include<bits/stdc++.h>
using namespace std;
int main() {string s; cin >> s;int ans = 0;for (int i = 0; i < s.size(); i++) {for (int j = i + 1; j < s.size(); j++) {string tmp = s;reverse(tmp.begin()+i, tmp.begin()+j+1); //反转子串s[i,j]if (tmp < s) ans++;}}cout << ans << endl;return 0;
}
java代码
import java.util.Scanner;
public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);String s = sc.next();int ans = 0;for (int i = 0; i < s.length(); i++) {for (int j = i + 1; j < s.length(); j++) {StringBuilder tmp = new StringBuilder(s);tmp.replace(i, j + 1, new StringBuilder(s.substring(i, j + 1)).reverse().toString());if (tmp.toString().compareTo(s) < 0) ans++; }}System.out.println(ans);}
}
python
s = input()
ans = 0
for i in range(len(s)):for j in range(i + 1, len(s)):tmp = list(s)tmp[i:j+1] = reversed(tmp[i:j+1])if ''.join(tmp) < s:ans += 1
print(ans)
用两种for循环遍历所有的子串。用库函数reverse()反转子串,如果不会用这个函数,也可以自己写一个反转子串的函数。
代码的计算复杂度是多少?两重for循环是 O ( n 2 ) O(n^2) O(n2),reverse()是O(n)的,总复杂度为 O ( n 3 ) O(n^3) O(n3)。只能通过40%的测试。
下面用DP求解本题,复杂度为 O ( n 2 ) O(n^2) O(n2),通过100%的测试。
1、DP状态设计
本题可以用DP吗?它有DP的重叠子问题和最优子结构吗?
在模拟法中,需要检查每个子串,为了应用DP,考虑这些子串之间有没有符合DP要求的关系,请读者思考。下面的DP状态设计和DP转移方程体现了子串之间的DP关系。
DP状态:定义二维数组dp[][],dp[i][j]表示子串s[i]~s[j]反转之后是否大于反转前的子串。dp[i][j]=1表示反转之后变小,符合要求;dp[i][j]=0表示反转之后没有变小。
在DP题目中,建议把状态命名为dp,这有利于与队友的交流。队友看到dp这个关键字,用不着解释,就知道这是一道DP题,dp是定义的状态,而不是别的意思。
2、DP转移方程
对于每个子串,比较它的首尾字符s[i]和s[j],得到状态转移方程。
(1)若s[i] > s[j],说明反转后的子串肯定小于原子串,符合要求,赋值dp[i][j] = 1。
(2)若s[i] < s[j],说明反转后的子串肯定大于原子串,赋值dp[i][j] = 0。
(3)若s[i] = s[j],需要继续比较s[i+1]和s[j-1],有dp[i][j] = dp[i+1][j-1]。
第(3)条的dp[i][j] = dp[i+1][j-1]是自顶向下的思路,例如dp[1][6] = dp[2][5],dp[2][5] = dp[3][4],等等。
计算这个递推公式时,需要先算出较小子串的dp[][],再递推到较大子串的dp[][]。例如先要计算出dp[2][5],才能递推到dp[1][6]。最小子串的dp[][],例如dp[1][1]、dp[1][2]、dp[2][2]、dp[2][3]等,它们不再需要递推,因为dp[1][1]=0,dp[1][2]根据(1)、(2)计算。
3、代码
根据上述思路,读者可能很快就写出了以下代码。
#include<bits/stdc++.h>
using namespace std;
int dp[5010][5010];
int main() {string s; cin >> s;int ans = 0;for (int i = 0; i < s.length(); i++) { //子串从s[i]开始for (int j = i+1; j < s.length(); j++) { //子串末尾是s[j]if (s[i] > s[j]) dp[i][j] = 1;if (s[i] < s[j]) dp[i][j] = 0;if (s[i] == s[j]) dp[i][j] = dp[i + 1][j - 1];if (dp[i][j] == 1) ans++;}}cout << ans;
}
代码的计算复杂度:两重for循环 O ( n 2 ) O(n^2) O(n2),优于前面模拟法代码的 O ( n 3 ) O(n^3) O(n3)。
代码看起来逻辑很清晰,但它其实是错误的。问题出在第7、8行的for循环。例如第7行i=0,第8行j=8时,递推得dp[0][8]=dp[1][7],但是此时dp[1][7]已经计算过吗?并没有。
递推的时候,根据DP的原理,应该先算出小规模问题的解,再递推大规模问题的解。计算应该这样进行:
(1)初始化:dp[][]=0,其中的dp[0][0]=0、dp[1][1]=0、…、dp[1][0]、…,在后续计算中有用。
(2)第一轮递推:计算长度为2的子串的dp[][],即计算出dp[0][1]、dp[1][2]、dp[2][3]、…。例如计算dp[0][1],若s0>s1,则dp[0][1]=1;若s0<s1,则dp[0][1]=0;若s0=s1,则dp[0][1]=dp[1][0]=0,这里dp[1][0]=0是初始化得到的。
(3)第二轮递推:计算长度为3的子串的dp[][],即计算出dp[0][2]、dp[1][3]、dp[2][4]、…。例如计算dp[0][2],若s0=s2,则有dp[0][2]=dp[1][1]=0,这时用到了前面得到的dp[1][1]。
(4)第三轮递推:计算长度为4的子串的dp[][],即计算出dp[0][3]、dp[1][4]、dp[2][5]、…。例如计算dp[0][3],若s0=s3,则有dp[0][3]=dp[1][2],这时用到了前面得到的dp[1][2]。
(5)继续递推,最后得到所有的dp[][]。
代码应该这样写,用循环变量k表示第k轮递推,或者表示递推长度为k+1的子串:
C++代码:
#include<bits/stdc++.h>
using namespace std;
int dp[5010][5010]; //全局数组,初始化为0
int main() {string s; cin >> s;int ans = 0;for (int k = 1; k < s.length(); k++) { //第k轮递推。k=j-ifor (int i = 0; i+k < s.length(); i++) { //子串从s[i]开始int j = i+k; //子串末尾是s[j]if (s[i] > s[j]) dp[i][j] = 1;if (s[i] < s[j]) dp[i][j] = 0;if (s[i] == s[j]) dp[i][j] = dp[i + 1][j - 1];if (dp[i][j] == 1) ans++;}}cout << ans;
}
java代码
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);String s = sc.next();int[][] dp = new int[5010][5010];int ans = 0;for (int k = 1; k < s.length(); k++) {for (int i = 0; i + k < s.length(); i++) {int j = i + k;if (s.charAt(i) > s.charAt(j)) dp[i][j] = 1; if (s.charAt(i) < s.charAt(j)) dp[i][j] = 0;if (s.charAt(i) == s.charAt(j))dp[i][j] = dp[i + 1][j - 1]; if (dp[i][j] == 1) ans++;}}System.out.println(ans);}
}
python代码
s = input()
dp = [[0] * 5010 for _ in range(5010)]
ans = 0
for k in range(1, len(s)):for i in range(len(s) - k):j = i + kif s[i] > s[j]: dp[i][j] = 1if s[i] < s[j]: dp[i][j] = 0if s[i] == s[j]: dp[i][j] = dp[i + 1][j - 1]if dp[i][j] == 1: ans += 1
print(ans)
4、对比DP代码和模拟代码
DP代码和模拟代码的相同处:它们都需要计算所有的子串,共 O ( n 2 ) O(n^2) O(n2)个子串。
为什么DP代码的效率更高呢?
(1)模拟代码对每个子串的计算是独立的。每个子串的计算和其他子串无关,不用其他子串的计算结果,自己的计算结果对其他子串的计算也没有用。每个子串需要计算O(n)次, O ( n 2 ) O(n^2) O(n2)个子串的总计算量是 O ( n 3 ) O(n^3) O(n3)的。
(2)DP的子串计算是相关的。长度为2的子串计算结果,在计算长度为3的子串时用到;长度为3的子串计算结果,在计算长度为4的子串时用到;…等等。所以一个子串的计算量只有O(1), O ( n 2 ) O(n^2) O(n2)个子串的总计算量是 O ( n 2 ) O(n^2) O(n2)的。这就是DP利用“重叠子问题”得到的计算优化。
4. 常见线性DP
线性DP是蓝桥杯省赛最常考核的题型。
本博客写过类似的博文,请参考:DP概述和常见DP面试题
非线性DP,蓝桥杯省赛可能考到的有:树形DP、状态压缩DP、数位DP。这属于较难的知识了,初学者以后再学。见专辑:DP专题
5. DP习题
2023年第14届省赛的DP题很多,大多是线性DP,大家可以作为练习题:
C/C++:A组“更小的数”、B组“接龙数列”、C组“填充”、研究生组“奇怪的数”。
Java:A组“高塔”、B组“ 数组分割,蜗牛,合并石子”、C组“填充”、研究生组“奇怪的数”。
Python:A组“奇怪的数”、B组“松散子序列,保险箱,树上选点”、C组“填充,奇怪的数”、研究生组“填充,高塔”。
相关文章:

<蓝桥杯软件赛>零基础备赛20周--第18周--动态规划初步
报名明年4月蓝桥杯软件赛的同学们,如果你是大一零基础,目前懵懂中,不知该怎么办,可以看看本博客系列:备赛20周合集 20周的完整安排请点击:20周计划 每周发1个博客,共20周。 在QQ群上交流答疑&am…...

vb如何获取鼠标形状的特征码
vb如何获取鼠标形状的特征码 好像按键精灵有一个GetCursorShape()函数可以获取特征码,不知道VB6能不能实现类似的功能? 附注: 1 最好是机器无关的,不是也可以。 2 特征码就是一串数字,用来区分不同的鼠标形状。 3 获取…...

chroot: failed to run command ‘/bin/bash’: No such file or directory
1. 问题描述及原因分析 在busybox的环境下,执行 cd rootfs chroot .报错如下: chroot: failed to run command ‘/bin/bash’: No such file or directory根据报错应该rootfs文件系统中缺少/bin/bash,进入查看确实默认是sh,换成…...

蓝桥杯备战——2.矩阵键盘
1.分析原理图 由上图可以看到若J5跳线帽接地,就S4~S7就可以当做四路独立按键,若接到P44,则就是4*4的矩阵键盘。 2.独立按键处理 相对传统的按键延时消抖方案,这里我采用更高效,更经典,更偏向产品级应用的…...

Docker部署思维导图工具SimpleMindMap并实现公网远程访问
文章目录 1. Docker一键部署思维导图2. 本地访问测试3. Linux安装Cpolar4. 配置公网地址5. 远程访问思维导图6. 固定Cpolar公网地址7. 固定地址访问 SimpleMindMap 是一个可私有部署的web思维导图工具。它提供了丰富的功能和特性,包含插件化架构、多种结构类型&…...

机器学习实验2——线性回归求解加州房价问题
文章目录 🧡🧡实验内容🧡🧡🧡🧡数据预处理🧡🧡代码缺失值处理特征探索相关性分析文本数据标签编码数值型数据标准化划分数据集 🧡🧡线性回归🧡&am…...

宝塔+nextcloud+docker+Onlyoffice 全开启https
折腾了我三天的经验分享 1.宝塔创建网站 nextcloud版本为28.0.1 php8.2 ,导入nextcloud绑定域名对应的证书 ,不用创建mysql 因为nextcloud 要求是mariadb:10.7 宝塔里没有,就用docker安装一个 端口设置为3307 将数据库文件映射出来/ww…...

呼吸机电机控制主控MCU方案
呼吸机是一种能代替、控制或改变人的正常生理呼吸,增加肺通气量,改善呼吸功能,减轻呼吸功消耗,节约心脏储备能力的装置。呼吸机连接一条管子到患者的嘴或鼻子,氧气量可以通过监视器加以控制。 基于灵动微控制器的呼吸…...

gitlab备份-迁移-升级方案9.2.7升级到15版本最佳实践
背景 了解官方提供的版本的升级方案 - GitLab 8: 8.11.Z 8.12.0 8.17.7 - GitLab 9: 9.0.13 9.5.10 9.2.7 - GitLab 10: 10.0.7 10.8.7 - GitLab 11: 11.0.6 11.11.8 - GitLab 12: 12.0.12 12.1.17 12.10.14 - GitLab 13: 13.0.14 13.1.11 13.8.8 13.12.15 - G…...

redis面试题合集-基础
前言 又来到每日的复习时刻,昨天我们学习了mysql相关基础知识,还有分布式数据库介绍(后续总结时再持续更新)。今日继续学习缓存杀器:redis redis基础面试题合集 什么是Redis? Redis是一个开源的、内存中…...

(Unity)C# 中的字符串格式化
前言 在软件开发中,理解和掌握字符串的格式化及调试技巧对于编写高效和可维护的代码至关重要。 字符串插值 ($ 符号) 在 C# 中,字符串插值是通过在字符串前加 $ 符号来实现的。这允许我们将变量、表达式或函数调用直接嵌入到字符串中。 string name &qu…...

【项目日记(五)】第二层: 中心缓存的具体实现(上)
💓博主CSDN主页:杭电码农-NEO💓 ⏩专栏分类:项目日记-高并发内存池⏪ 🚚代码仓库:NEO的学习日记🚚 🌹关注我🫵带你做项目 🔝🔝 开发环境: Visual Studio 2022 项目日…...

使用PSIM软件生成DSP28335流水灯程序
最近在学习DSP28335芯片,然后在使用PSIM仿真软件时发现这个仿真软件也支持28335芯片,于是就想学习下如何在PSIM软件中使用DSP28335芯片。在PSIM自带的官方示例中有使用DSP28335芯片的相关例子。 工程下载链接 https://download.csdn.net/download/qq_20…...

【iOS ARKit】人脸检测追踪基础
在计算机人工智能(Artificial Inteligence,AI)物体检测识别领域,最先研究的是人脸检测识别,目前技术发展最成熟的也是人脸检测识别。人脸检测识别已经广泛应用于安防、机场、车站、闸机、人流控制、安全支付等众多社会领域&#x…...

ES的一些名称和概念总结
概念 先看看ElasticSearch的整体架构: 一个 ES Index 在集群模式下,有多个 Node (节点)组成。每个节点就是 ES 的Instance (实例)。每个节点上会有多个 shard (分片), P1 P2 是主分片, R1 R2…...

Javaweb之SpringBootWeb案例之阿里云OSS服务集成的详细解析
2.3.3 集成 阿里云oss对象存储服务的准备工作以及入门程序我们都已经完成了,接下来我们就需要在案例当中集成oss对象存储服务,来存储和管理案例中上传的图片。 在新增员工的时候,上传员工的图像,而之所以需要上传员工的图像&…...

【GitHub项目推荐--不错的 Go 学习项目】【转载】
开源实时性能分析平台 Pyroscope 是基于 Go 的开源实时性能分析平台,在源码中添加几行代码 pyroscope 就能帮你找出源代码中的性能问题和瓶颈、CPU 利用率过高的原因,调用树展示帮助你理解程序,支持 Go、Python、Ruby 语言。 Pyroscope 可以…...

【Git】windows系统安装git教程和配置
一、何为Git Git(读音为/gɪt/)是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。 二、git安装包 有2种版本,Git for Windows Setup和Git for Windows Portable(便携版)两个版本都可以。 三、Git for Windows Por…...

办公技巧:PPT制作技巧分享,值得收藏
目录 1、黑屏/白屏你用过么 2、图形组合替代动画刷 3、等距分布图形元素 4、快速统一字体 5、文本框也是可以改的 6、批量修改形状 7、搞定“怎么也选不中” 8、妙用CtrlD 9、图片阵列怎么做 10、临时放大某一区域 11、Word快速导入PPT 12、炫酷小人怎么做的&#…...

Google Chrome RCE漏洞 CVE-2020-6507 和 CVE-2024-0517 流程分析
本文深入研究了两个在 Google Chrome 的 V8 JavaScript 引擎中发现的漏洞,分别是 CVE-2020-6507 和 CVE-2024-0517。这两个漏洞都涉及 V8 引擎的堆损坏问题,允许远程代码执行。通过EXP HTML部分的内存操作、垃圾回收等流程方式实施利用攻击。 CVE-2020-…...

前端怎么监听手机键盘是否弹起
摘要: 开发移动端中,经常会遇到一些交互需要通过判断手机键盘是否被唤起来做的,说到判断手机键盘弹起和收起,应该都知道,安卓和ios判断手机键盘是否弹起的写法是有所不同的,下面讨论总结一下两端的区别以及…...

本地生活服务平台加盟前景与市场分析
随着短视频市场的的不断发展,人们的生活方式也在发生着巨大的变化。在这个数字化的时代,越来越多的创业者开始注重本地生活服务,这也为创业者提供了一个绝佳的商机。加盟本地生活服务平台,既可以抓住这波风口,又可以满…...

蓝桥杯备战——7.DS18B20温度传感器
1.分析原理图 通过上图我们可以看到DS18B20通过单总线接到了单片机的P14上。 2.查阅DS18B20使用手册 比赛的时候是会提供DS18B20单总线通讯协议的代码,但是没有提供读取温度数据的代码,所以还是需要我们去查看手册,我只把重要部分截下来了 …...

黑盒测试用例的具体设计方法(7种)
7种常见的黑盒测设用例设计方法,分别是等价类、边界值、错误猜测法、场景设计法、因果图、判定表、正交排列。 (一)等价类 1.概念 依据需求将输入(特殊情况下会考虑输出)划分为若干个等价类,从等价类中选…...

docker镜像管理命令
文章目录 docker imagesdocker builddocker rmidocker tagdocker savedocker loaddocker importdocker commitdocker login/logoutdocker pulldocker pushdocker search总结 docker images 列出本地镜像。 docker images [OPTIONS] [REPOSITORY[:TAG]]OPTIONS说明:…...

深入理解STM32中断处理机制
深入理解STM32中断及其使用方法(基于HAL库) STM32微控制器作为一款强大的嵌入式系统芯片,在各种应用中都需要使用中断来实现实时响应和处理各种事件。本文将深入讨论STM32中断的概念、HAL库的中断处理机制以及如何在STM32CubeMX中配置和使用…...

基于机器学习的地震预测(Earthquake Prediction with Machine Learning)
基于机器学习的地震预测(Earthquake Prediction with Machine Learning) 一、地震是什么二、数据组三、使用的工具和库四、预测要求五、机器学习进行地震检测的步骤六、总结 一、地震是什么 地震几乎是每个人都听说过或经历过的事情。地震基本上是一种自…...

《30天自制操作系统》 第一周(D1-D7) 笔记
前言:这是我2023年5月份做的一个小项目,最终是完成了整个OS。笔记的话,只记录了第一周。想完善,却扔在草稿箱里许久。最终决定,还是发出来存个档吧。 一、汇编语言 基础指令 MOV: move赋值,数据传送指令…...

SQL注入:报错注入
SQL注入系列文章:初识SQL注入-CSDN博客 SQL注入:联合查询的三个绕过技巧-CSDN博客 目录 什么是报错注入? 报错注入常用的3个函数 UpdateXML ExtractValue Floor rand(随机数) floor(向上取整&…...

K8s 安装部署-Master和Minion(Node)文档
K8s 安装部署-Master和Minion(Node)文档 操作系统版本:CentOS 7.4 Master :172.20.26.167 Minion-1:172.20.26.198 Minion-2:172.20.26.210(后增加节点) ETCD:172.20.27.218 先安装部署ETC…...