在这里插入图片描述
每日激励:“不设限和自我肯定的心态:I can do all things。 — Stephen Curry”

绪论​:
本章是动态规划算法的基础入门篇,我将通过三道简单题 + 一道中等难度的一维动态规划题来带你对动态规划有个初认识,并基本了解动态规划的最基本常见的写法,只有将基本写法了解了,对后续的难的题目自然也不会毫无头绪,后续还将持续更新更多相关的动规算法,敬请期待~🙃
————————
早关注不迷路,话不多说安全带系好,发车啦(建议电脑观看)。


👻动态规划🌥️

这里通过大量练习得出下面动态规划做题步骤
简单的说动态规划理解成:某种状态的公式 + 提前求出来值的容器出当前位置的值然后放到容器中后后续使用
因为最开始的值一般是会看见的所以就能有初始值,从而启动动态规划

从上中可以主要提炼出:

  • 状态
  • 容器的重要性
  • 公式,可以换种说法:状态转移方程

这样严格😈的说:动态规划 = 状态定义 + 状态转移方程 + 初始条件 + 状态存储(容器)


下述步骤是通过写完下述四道题后的总结,所以同样需要道友🗡️大量的练习沉淀最终就能对动态规划的题目有一个基本的了解和思路,同时建议这里先一眼看过在做题中不断的磨炼同时再看这里,慢慢的找感觉。


动规基本步骤

  1. 状态表示:就是dp表(容器一般是数组)中里面的dp[ i ]值的含义
    1. 通过经验 + 题目要求:通常为:以 i 位置结尾,xxxxx
    2. 分析问题的过程中,发现相同的子问题
  2. 状态转移方程:本质就是 dp[ i ] = ?也是最难的一步
    1. 通过状态表示 再结合 题目含义推导处dp[ i ]的值到底为多少
  3. 初始化
    1. 保证填表的时候不越界
    2. 主要也是根据题目进行
  4. 填表顺序
    1. 为了保证填写当前状态的时候前面状态已经存到容器中,这样才能进行计算
    2. 一般是从左向右/从上到下
  5. 返回值
    1. 通过最终得到的dp表和题意找到dp表中的结果

附⭐⭐⭐:

  1. 状态表示:通常为:以 i 位置结尾/开头,xxxxx
  2. dp[ i ] 通常通过最后一个状态来进行分析
  3. 初始化 通常通过第一个状态来进行分析
  4. 再做类似数字判断时,不要使用字符来简单的判断,而是将数字字符根据位数转变为真正的数字然后再进行判断,不要偷懒会容易出现不可控的情况(具体见题目4)
  5. 适当的需要的情况下可以开辟空间来处理边界问题,这点在后面稍微进阶一点的动规来说就是使用的更多

🥴话不多说,从题目来以练代学式的快速上手,我也会边分析过程边使用上述的5步骤


具体训练:

1. 第 N 个泰波那契数🤓

题目🍪:

在这里插入图片描述

分析题目并提出,解决方法📕:

在这里插入图片描述

回顾五大步骤:

  1. 状态表示:就是dp表中里面的值的含义

在这里插入图片描述
怎么来

  1. 经验 + 题目要求
  2. 分析问题的过程中,发现子问题
  1. 状态转移方程:本质就是dp[ i ] 等于什么(也是最难的一步)
    1. 根据状态表示 + 题目含义得出
  2. 初始化
    1. 保证填表的时候不越界
    2. 也是根据题目意思进行填写
  3. 填表顺序
    1. 为了填写当前状态的时候,所需要的状态已经计算过了
    2. 一般是从左向右/从上到下
  4. 返回值
    1. 题目要求 + 状态表示

题解核心逻辑✍️:

  1. 状态表述:dp[ i ]:第 i 个泰波那契数
    1. 根据经验 + 题目要求
  2. 本题的转移方程: dp[ i ] = dp[ i - 1 ] + dp[ i - 2 ] + dp[ i - 3 ](通过上图总的公式直接得出)
  3. 初始化,对本题的 dp[0]、dp[1]、dp[2] 这三个位置初始化,才能进行正常的开始
    在这里插入图片描述
  4. 填表顺序
    1. 需要在求第 i 位置那么: i - 1、i - i、i -3 三个位置的值都得算好
    2. 所以需要:从左向右
      在这里插入图片描述
  5. 返回值
    1. 题目要求:第 n 个的值 dp[ n ]即可
  6. 空间优化:当我们在填某个表,某个状态只需要前面的若干个状态时,就可以使用滚动数组进行优化,本题仅需要某个数的前3个即可
    1. 本题仅需要3个变量abc来标明前3个数,求d的数
    2. 通过移动 abcd 四个数,来代替dp表
      在这里插入图片描述

源码🗒️

class Solution {
public:int tribonacci(int n) {//1. 状态表示:dp[i] = 第i个泰波那契序列//2. 状态表示:Tn+3 = Tn + Tn+1 + Tn+2 -> dp[i] = dp[i-1] + dp[i-2] + dp[i-3]vector<int> dp(n + 1);//提前开辟好 n 个位置的空间,注意从0开始所以+1//3. 初始化:需要前三个 那么就是初始化 0 1 2,从3开始dp[0] = 0,dp[1] = 1,dp[2] = 1;//4. 填表顺序:要求的值是Ti,那么求就是 dp[i],所以肯定是从小的开始,也就是从左往右for(int i = 3;i <= n;i++){dp[i] = dp[i-1] + dp[i-2] + dp[i-3];//这里本质就是使用状态转移方程}//5. 返回值:dp[i]即可return dp[n];}int tribonacci(int n) {//空间优化写法:int a = 0,b = 1,c = 1;int ret = 0;if(n == 0) return 0; if(n == 1 || n == 2) return 1; for(int i = 3 ; i <= n;i++){//填表顺序ret = a + b + c;a = b;b = c;c = ret;}return ret;}
};

2. 三步🚶问题

题目👻:

在这里插入图片描述

分析题目并提出,解决方法🫏:

这里主要理解成:

  • 本题分析不难看出:要求到达某个台阶的方法(这里就能简单的看出来状态表示
  • 直接拿示例一来看:如何到达台阶n=3:
    1. 也很简单:因为小孩每次可以走1/2/3步,那么那几个阶能到达呢?
    2. 无非就是 n - 1、n - 2 、n - 3 (这里n=3,故从0 1 2阶能到达这里就能看出来状态转移方程: dp[n] = dp[n-1] + dp[n-2] + dp[n-3]
    3. 那么要初始化的就是 dp[0]、dp[1]、dp[2]
    4. 从状态表示也能很简单的推出,因为本质阶梯不高:
      1. dp[0]:走到0,那么就是不用走也就是走0步,故为1
      2. dp[1]:走到1,只能从0走一步,故也为1
      3. dp[2]:走到2,那么就能从0走2步和从1走1步,所以为2
    5. 剩下就是移动方向:自然和上题一样从左往右、返回dp[n]即可

再拿走到4来看:

  • 向下的 1 2 3 个台阶,如能到达4的就是 3 2 1
  • 那么到达4的方法就是:到达 3 2 1 台阶的方法之和

在这里插入图片描述

题解核心逻辑🚶:

现在推出来了:

  1. 状态表示(经验 (以某个位置结尾/以某个位置起始) + 题目要求)
    1. dp[ i ] 表示到达i个台阶一共有多少个方法
      在这里插入图片描述
  2. 状态转移方程:以 i 位置的状态,最近的一步,来划分问题
    1. dp[i] 分为三种情况:
    2. 从 i - 1 -> i:dp[ i - 1 ]
    3. 从 i - 2 -> i:dp[ i - 2 ]
    4. 从 i - 3 -> i:dp[ i - 3 ]
    5. 所以:dp[ i ] = dp[ i - 1 ] + dp[ i - 2 ] + dp[ i - 3 ]
      在这里插入图片描述
  3. 初始化:
    1. dp[0] = 1
    2. dp[1] = 1
    3. dp[2] = 2
  4. 填表顺序:从左往右
  5. 返回值:dp[n]
class Solution {
public:int waysToStep(int n) {//1. 状态表示:dp[n] 计算小孩上到 n 阶台阶有多少种上楼梯的方式//2. 状态方程:dp[i] = dp[i-1] + dp[i-2] + dp[i-3] 本质还是很上题一样vector<int> dp(n+3);//这里的初始化同样要注意因为可能n较小所以需要+3//3. 初始值:同样的 0 1 2,但本题的初始化就没那么简单了// 也希望你能很好的体会 状态表示的作用:确定每个状态点i位置的值dp[0] = 1;//到达0阶有几种dp[1] = 1;//到达1阶有几种dp[2] = 2;//到达2阶有几种if(n <= 2) return dp[n];//4. 方向:同样需要求 i 就得先找到 i-3... 那么就得从左往右for(int i = 3;i <= n;i++){dp[i] = ((long)dp[i-1] + dp[i-2] + dp[i-3]) % 1000000007;//这里本质就是使用状态转移方程}//5. 返回dp[n]即可return dp[n];}//写法二:int waysToStep(int n) {vector<int> dp(n + 3);dp[1] = 1;dp[2] = 2;dp[3] = 4; //另外一种看法忽律0台阶直接从1开始,方法类似不过多叙述for(int i = 4;i<=n;i++){dp[i] = ((long)dp[i-1] + dp[i-2] + dp[i-3]) % 1000000007;}return dp[n];}
//写法三:
//这里优化就不写了贴一份别人的:作者:Spectreint waysToStep(int n) {// 时间复杂度O(N),空间复杂度O(1)if (n == 1 || n == 2) return n;if (n == 3) return 4;int dp1 = 1, dp2 = 2, dp3 = 4, dp4;for (int i = 4; i <= n; ++i) {dp4 = ((dp1 + dp2) % 1000000007 + dp3) % 1000000007;dp1 = dp2;dp2 = dp3;dp3 = dp4;}return dp4;}};

在这里插入图片描述

3. 使用最小花费爬楼梯🪜

题目📕:

在这里插入图片描述

分析题目并提出,解决方法✍️:

  • 楼顶在最后
    在这里插入图片描述

题解核心逻辑🎈:

解法一:

  1. 状态表示(经验+题目要求):
    1. 以 i 位置为结尾,xxx:
    2. 所以:dp[ i ] 表示:到达 i 位置时,最小花费
  2. 状态转移方程
    1. 用之前 或者 之后的状态,推导出dp[ i ] 的值
      在这里插入图片描述
    2. 根据最近的一步,来划分问题
    3. 先到达 i - 1,然后支付 cost[ i-1 ],走一步:dp[ i - 1] + cost[ i - 1 ]
    4. 先到达 i - 2,然后支付 cost[ i-2 ],走两步:dp[ i - 2 ] + cost[ i - 2]
    5. 所以dp[ i ] = min( dp[ i - 1] + cost[ i - 1 ] , dp[ i - 2 ] + cost[ i - 2] )
  3. 初始化(防止越界,因为会用到 i - 1 和 i - 2 两个位置的值):
    1. 因为dp[ 0 ] = dp[ -1 ] + dp[ -2 ]这是没必要的,从题目可知
    2. 0 1 台阶是0元,所以直接从 2 开始即可
    3. 所以初始化 dp[0] = dp[1] = 0
      在这里插入图片描述
  4. 填表顺序:由题意从左往右
  5. 返回值:dp[n]
class Solution {
public:int minCostClimbingStairs(vector<int>& cost) {// cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用// 爬到楼顶本质就是超过容器个数 size=3 就需要爬到4(下标3)// 1. dp[i]:到达第i层需要的 最小 花费int n = cost.size();vector<int> dp(n+1); // 2. 状态转移方程: dp[i] = min(dp[i-1],dp[i-2]) + cost[i] 因为只能从下两层爬上来 + 当前需要的价值,注意的是cost[size]是越界的,此时+0即可// 3. 初始化:最小情况: dp[2] = min(dp[1],dp[0]) + cost[2] ,故初始化dp[1] dp[2] 即可dp[1] = cost[1];dp[0] = cost[0];for(int i = 2;i<= n;i++){if(i == n) dp[i] = min(dp[i-1],dp[i-2]);else dp[i] = min(dp[i-1],dp[i-2]) +cost[i];}return dp[n];}
};

在这里插入图片描述

方法二👻:

  1. 状态表示:
    1. 以 i 位置为起点,xxx
      在这里插入图片描述
    2. dp[ i ]:从 i 位置开始,到达楼顶,此时的最小花费
  2. 状态转移方程
    1. 用之前或者之后的状态推导
    2. 支付cost[i],往后走一步,从 i + 1 位置出发到达终点 dp[ i + 1 ] + cost[ i ]
    3. 支付 cost[ i ],往后走两步,从 i + 2 位置出发到达终点 dp[ i + 2 ] + cost[ i ]
    4. dp[ i ] = min( dp[ i + 1 ] + cost[ i ],dp[ i + 2 ] + cost[ i ]);
      在这里插入图片描述
  3. 初始化:
    1. dp[ n - 1 ] = cost [ n - 1 ]
    2. dp [ n - 2 ] = cost[ n - 2 ]
      在这里插入图片描述
  4. 填表顺序:从右往左
  5. 返回值:min(dp[0],dp[1])

这里就不扩展写了,感兴趣的可以实践下

中断总结🗒️一下:

  1. 通过上述好几道题不难总结出常用的状态表示经验:
    1. 以 i 位置为结尾,xxx
    2. 以 i 位置为开始,xxx

🥴通过上述三道题,估计你对动态规划中的最基本的步骤和思想都有一定的认识了,下面就不将是简单的套公式了,而是结合一些内容进一步深化对动态规划的理解
也就需要你在抽象的题目中提解出动态规划~~🤔
🤓本质也就是:状态表示不简单了、状态方程也没那么好推导了


4. 解码方法

题目🪜:

在这里插入图片描述
在这里插入图片描述

分析题目并提出,解决方法✍️:

在这里插入图片描述
本题如何想到的呢:从最后一个节点来看,不难发现规律:
在这里插入图片描述

  1. 要求第i位置的能否解码,就只用考略
    1. 当前位置i是否符合(0 <= i <= 9)
    2. i位置与i-1位置结合时是否符合(10 <= i-1 + i <= 26)
  2. 要求总共的解码个数,则是通过dp表存储每个节点的解码个数,最小的情况是很容易推算的,所以使用动规中的dp表是能进行存储的
  3. 通过上面两个想法也就不难得出状态转移方程如何计算
    1. 判断能否解码的两种方法,看这两种方法那个符合条件,若符合条件就记录上存储进dp表中
    2. 若不能解码的当然就不计算
    3. 具体见下面详细五步

题解核心逻辑🎈:

  1. 状态表示:
    1. 以 i 结尾时,解法方法的总数
  2. 状态转移方程
    1. 根据最近的一步划分问题:
    2. 分为两种情况:
      1. dp[ i ]单独解码( 1 ~ 9 ):解码成功(个数为 dp[ i -1 ]:因为本质就是拼接了一个新字母🤔这里好好理解下,并不用+1哦),失败则为0
      2. dp[ i ] 与 dp[ i - 1 ] 结合解码( 10 ~ 26 ) :解码成功(dp[ i - 2 ] 本质就是拼接两个新字母),失败则为0
        在这里插入图片描述
  3. 初始化:dp[ 0 ] 、dp[ 1 ]
  4. 填表顺序:根据状态转移方程得知从左往右
  5. 返回值:dp[ n - 1 ],n - 1最后一个位置

优化:处理边界问题以及初始化问题的技巧🤓

整个数组多开一位,然后通过使用这个多开的一位虚拟节点的初始化来帮助运算
注意的事项:

  1. 虚拟节点的初始化是根据题目意思来的,保证后面填表的正确
    1. 一般来说填写0
    2. 但本题对于该虚拟节点的使用,为了求原dp表中的dp[ 1 ] 时使用的 dp[ i - 2 ]
    3. 因为假设 dp[ 1 ] 和 移动后就变成了 dp[ 2 ],此时要求dp[ 2 ] 需要dp[ 1 ] 和 dp [ 0 ]
    4. dp [ 1 ] 本质就是原dp数组中的dp[ 0 ] 所以不会有问题
    5. 但dp[ 0 ] 就需要我们自己控制,回顾状态转移方程,这里dp[ i - 2 ]的作用是当 i 和 i - 1结合成功时取的值,所以填1(因为前面也没字符判断了,所以填1给到dp[2],代表正确)
      在这里插入图片描述
  2. 注意下标的映射关系,在真正使用dp时,因为dp表是多一格,对于s字符串中的下标要 - 1:s[i-1]
class Solution {
public:int dp[101] = {};int numDecodings(string s) {//初始化 0 和 1dp[0] = 1;//虚拟节点if( 1 <=  s[0] - '0' &&  s[0] - '0' <= 9) dp[1] = 1 ;//原dp[0]//移动s字符下标完成:for(int i = 2; i <= s.size();i++){//单个字符int onechar = s[i - 1] - '0'; if( 1 <= onechar && onechar <= 9) dp[i] += dp[i-1];//两个字符int combine = (s[i - 2] - '0') * 10 + onechar;if(10 <= combine && combine <= 26) dp[i] += dp[i-2];if(dp[i] == 0) return 0;}return dp[s.size()];}
};解法二:
class Solution {
public:int numDecodings(string s) {//dp[i]:以i位置结尾的解码个数://dp[i] = dp[i-1] + dp[i-2],其中若若不能解码则不进行相加,或者加0//初始化:因为s.length >= 1,所以需要一个多的空位,来特殊处理等于1的情况int n = s.size();vector<int> dp(n+2);//结果存在n下标dp[0] = 1; //默认解码个数为1次dp[1] = 1; //默认解码个数为1次if(s[0] == '0') return 0;//处理dp下标完成存储效果for(int i = 0; i < n;i++){//不要简单的字符判断!!!!!!!!!!!// if(i-1 >= 0 && s[i-1] - '0' >= 1 && s[i-1] - '0' <= 2 && //    s[i] - '0' >= 0 && s[i] - '0' <= 6) dp[i+2] += dp[i];int val = s[i] - '0';if(val >= 1 && val <= 9) dp[i+2] += dp[i+1];int combine = i-1 >= 0 ? ( s[i-1] - '0') * 10 + val : -1;if(combine >= 10 && combine <= 26)  dp[i+2] += dp[i];}return dp[n+1];}
};

对于需要判断两位或者多位数字时,不要图方便使用字符判断,而是将他转换为数字😭

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

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

相关文章

深入对比Tomcat与Netty:HTTP请求从网卡到Controller的全链路追踪

我们日常用Spring Boot写的RestController&#xff0c;感觉上就是一个简单的方法&#xff0c;但它背后其实有一套复杂的网络服务在支撑。一个HTTP请求到底是怎么从用户的浏览器&#xff0c;穿过层层网络&#xff0c;最终抵达我们代码里的Controller方法的&#xff1f;理解这个过…

GO学习记录十——发包

记录下不同平台的发包操作和期间遇到的问题 1.命令&#xff1a; $env:GOOSlinux $env:GOARCHamd64 go build -o release/HTTPServices-linux第一行&#xff0c;配置平台&#xff0c;linux、windows 第二行&#xff0c;配置部署服务器的处理器架构 第三行&#xff0c;输出目标文…

贪心算法与动态规划

1. 什么是贪心算法&#xff1f; 贪心算法是一种在每一步选择中都采取在当前状态下最好或最优&#xff08;即最有利&#xff09;的选择&#xff0c;从而希望导致结果是全局最好或最优的算法。 核心思想&#xff1a;“每步都贪心地选择眼前最好的&#xff0c;不去考虑整个未来的长…

学会“读网页”:生成式 AI 在足球赛事信息整理中的实战

逐步教程&#xff08;Step-by-Step&#xff09; — 适合初学者与教学类文章 背景&#xff08;为什么要这样做&#xff09; 对于足球迷、资讯编辑与数据分析师来说&#xff0c;最快、最准确把握一场比赛的核心信息至关重要&#xff1a;比分、关键事件&#xff08;进球、点球、红…

BM3D 图像降噪快速算法的 MATLAB 实现

BM3D 图像降噪快速算法的 MATLAB 实现1. 快速 BM3D 算法流程&#xff08;概述&#xff09;步骤操作加速技巧① 分组块匹配 堆叠FFT 互相关② 协同滤波3D 变换 硬阈值FFT 沿第三维③ 聚合加权平均稀疏矩阵累加 2. 核心函数&#xff08;单文件版&#xff09; 保存为 bm3d_fast.…

Go的schedt调度(runtime/proc.go)

1. 创建go的入口函数// Create a new g running fn. // Put it on the queue of gs waiting to run. // The compiler turns a go statement into a call to this. func newproc(fn *funcval) {gp : getg()pc : sys.GetCallerPC()systemstack(func() {newg : newproc1(fn, gp, …

Ubuntu 服务器配置转发网络访问

配置文档&#xff1a;Ubuntu 服务器转发网络访问 一、网络拓扑以以下网络拓扑为示例Ubuntu 服务器&#xff08;两个网卡&#xff09; eth1 10.66.71.222 &#xff08;接入内网&#xff09;eno1 192.168.2.100 &#xff08;直连相机&#xff09; 相机ip 192.168.2.1 Windows 客…

为什么企业需要高防IP

1. 抵御日益猖獗的DDoS攻击 现代DDoS攻击规模已突破Tbps级别 传统防火墙无法应对大规模流量攻击 高防IP采用分布式清洗中心&#xff0c;可轻松抵御300Gbps以上的攻击流量 2. 保障业务连续性 网络中断1小时可能造成数百万损失 高防IP确保服务99.99%可用性 智能切换机制实…

CSS基础 - 选择器备忘录 --笔记5

目录基础选择器组合器伪类选择器属性选择器选择器可以选中页面上的特定元素并为其指定样式。 CSS有多种选择器。 基础选择器 标签选择器 – tagname&#xff1a;匹配目标元素的标签名。优先级是0,0,1。如&#xff1a;p、h1、div类选择器 – .class&#xff1a;匹配class属性中…

自动驾驶中的传感器技术46——Radar(7)

卫星雷达&#xff08;又称为分布式雷达&#xff09;主要讲当前雷达的雷达信号处理计算以及雷达目标相关的一些感知算法都迁移到中央域控进行&#xff0c;雷达端基本只负责数据采集&#xff0c;这样做的影响如下&#xff1a; 雷达端成本与功耗降低&#xff1b; 雷达端采样得到的…

【论文阅读】Diff-Privacy: Diffusion-based Face Privacy Protection

基于扩散模型的人脸隐私保护方法——DiffPrivacy&#xff0c;解决了两类人脸隐私任务&#xff1a;匿名化&#xff08;anonymization&#xff09;和视觉身份信息隐藏&#xff08;visual identity information hiding&#xff09;。1. 研究背景随着人工智能和大数据技术的普及&am…

React 原理篇 - 深入理解虚拟 DOM

一、什么是虚拟 DOM&#xff1f; 在前端开发中&#xff0c;“虚拟 DOM” 是一个高频出现的术语&#xff0c;尤其在 React 生态中被广泛讨论。但很多开发者对它的理解往往停留在 “JS 对象” 这个表层认知上。 实际上&#xff0c;虚拟 DOM 是一种编程概念—— 在这个概念里&…

对汇编的初理解

此处是一个简单的函数&#xff0c;里面将调用了一个函数add&#xff08;&#xff09;函数这里是函数的原型这里是调用lcd函数产生的汇编语言&#xff0c;翻译过来就是r11&#xff0c;r0cnt(r4cnt,前文有提及)&#xff0c;然后调用add函数&#xff0c;此处BL是指会回到指令的下一…

《Python 自动化实战:从零构建一个文件同步工具》

《Python 自动化实战:从零构建一个文件同步工具》 一、开篇引入:为什么我们需要文件同步? 你是否有过这样的困扰: 公司电脑和家里电脑上都有工作项目,每次更新都要手动复制? U 盘频繁传输文件,不仅麻烦还容易出错? 项目文件夹动辄几 G,每次同步都耗时长、效率低? 在…

工业相机与镜头的靶面尺寸详解:选型避坑指南

在机器视觉系统中&#xff0c;相机与镜头的靶面尺寸匹配是一个非常关键却又经常被忽略的细节。选错了&#xff0c;不但影响图像质量&#xff0c;还可能导致画面“黑角”、视野不符、镜头浪费等问题。 今天我们就用通俗易懂的方式&#xff0c;聊一聊相机与镜头靶面尺寸的那些事儿…

使用 Go 和 go-commons 实现内存指标采集并对接 Prometheus

文章目录一、准备工作二、编写内存采集代码三、运行 Exporter四、接入 Prometheus五、可扩展思路总结在运维和监控领域&#xff0c;资源指标采集 是必不可少的一环。CPU、内存、磁盘、网络这些系统资源&#xff0c;需要实时采集并上报到监控系统中。 本文以 内存指标采集 为例&…

webrtc弱网-IntervalBudget类源码分析与算法原理

一、核心功能 IntervalBudget 类用于基于时间窗口的带宽预算管理。它根据设定的目标比特率&#xff08;kbps&#xff09;和一个固定时间窗口&#xff08;500ms&#xff09;&#xff0c;计算在该时间窗口内可用的字节数&#xff08;即“预算”&#xff09;&#xff0c;并支持预…

深度学习基本模块:RNN 循环神经网络

循环神经网络&#xff08;RNN&#xff09;是一种专门用于处理序列数据的神经网络架构。与处理空间数据的卷积神经网络&#xff08;Conv2D&#xff09;不同&#xff0c;RNN通过引入循环连接使网络具有"记忆"能力&#xff0c;能够利用之前的信息来影响当前的输出&#…

React18学习笔记(二) React的状态管理工具--Redux,案例--移动端外卖平台

文章目录一.Redux的基础用法1.示例:普通网页中的Redux计步器2.Redux管理数据的流程3.配套工具和环境准备3.1.配套工具3.2.环境准备4.示例:React项目中的Redux计步器思路步骤step1:创建子模块step2:导入子模块step3:注入store实例step4:React组件内使用store中的数据step5:在组件…

34.Socket编程(UDP)(上)

点分十进制字符串IP 转 32位网络序列IP 分析&#xff1a;1&#xff09;IP转成4字节 2&#xff09;4字节转成网络序列 思路&#xff1a; "192.168.1.1" 进行字符串划分&#xff0c;以 "." 为分割符&#xff0c;分割出"192"&#xff0c;&qu…