线性DP(动态规划)
线性DP的概念(视频)
学习线性DP之前,请确保已经对递推有所了解。
一、概念
1、动态规划
不要去看网上的各种概念,什么无后效性,什么空间换时间,会越看越晕。从做题的角度去理解就好了,动态规划就可以理解成一个 有限状态自动机,从一个初始状态,通过状态转移,跑到终止状态的过程。
2、线性动态规划
线性动态规划,又叫线性DP,就是在一个线性表上进行动态规划,更加确切的说,应该是状态转移的过程是在线性表上进行的。我们考虑有 0 到 n 这 n+1 个点,对于第 i 个点,它的值取决于 0 到 i-1 中的某些点的值,可以是求 最大值、最小值、方案数 等等。
很明显,如果一个点 i 可以从 i-1 或者 i-2 过来,求到达第 i 号点的方案数,就是我们之前学过的斐波那契数列了,具体可以参考这篇文章:递推。
二、例题解析
1、题目描述
给定一个 n,再给定一个 n(n ≤ 1000) 个整数的数组 cost, 其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦支付此费用,即可选择向上爬 1个 或者 2个 台阶。可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯,请计算并返回达到楼梯顶部的最低花费。
2、算法分析
我们发现这题和之前的爬楼梯很像,只不过从原来的计算 方案数 变成了计算 最小花费。尝试用一个数组来表示状态:f[i] 表示爬到第 i 层的最小花费。
由于每次只能爬 1个或者 2个台阶,所以 f[i] 这个状态只能从 f[i-1] 或者 f[i-2] 转移过来:
1)如果从 i-1 层爬上来,需要的花费就是 f[i-1] + cost[i-1];
2)如果从 i-2 层爬上来,需要的花费就是 f[i-2] + cost[i-2];
没有其他情况了,而我们要 求的是最小花费,所以 f[i] 就应该是这两者的小者,得出状态转移方程:
f[i] = min(f[i-1] + cost[i-1], f[i-2] + cost[i-2])
然后考虑一下初始情况 f[0] 和 f[1],根据题目要求它们都应该是 0。
3、源码详解
int min(int a, int b) {return a < b ? a : b; // (1)
}int minCostClimbingStairs(int* cost, int n){int i; // (2)int f[1001] = {0, 0}; // (3)for(i = 2; i <= n; ++i) { // (4)f[i] = min(f[i-1] + cost[i-1], f[i-2] + cost[i-2]);}return f[n]; // (5)
}
- (1) 为了方便求最小值,我们实现一个最小值函数 min,直接利用 C语言 的 条件运算符 就可以了;
- (2) 然后开始动态规划的求解,首先定义一个循环变量;
- (3) 再定义一个数组 f[i] 代表从第 0 阶爬到第 i 阶的最小花费,并且初始化第 0 项 和 第 1 项;
- (4) 然后一个 for 循环,从第 2 项开始,直接套上状态转移方程就能计算每一项的值了;
- (5) 最后返回第 n 项即可;
三、再谈动态规划
经典的线性DP有很多,比如:最长递增子序列、背包问题 是非常经典的线性DP了。建议先把线性DP搞清楚以后再去考虑其它的动态规划问题。
而作为动态规划的通解,主要分为以下几步:
1、设计状态
2、写出状态转移方程
3、设定初始状态
4、执行状态转移
5、返回最终的解
一、基本概念
学习动态规划,如果一上来告诉你:最优子结构、重叠子问题、无后效性 这些抽象的概念,那么你可能永远都学不会这个算法,最好的方法就是从一些简单的例题着手,一点一点去按照自己的方式理解,而不是背概念。
对于动态规划问题,最简单的就是线性动态规划,这堂课我们就利用一些,非常经典的线性动态规划问题来进行分析,从而逐个击破。
二、常见问题
1、爬楼梯
- 问题描述:有一个 n 级楼梯,每次可以爬 1 或者 2 级。问有多少种不同的方法可以爬到第 n 级。
- 状态:dp[i] 表示爬到第 i 级楼梯的方案数。
- 初始状态:dp[0] = dp[1] = 1
- 状态转移方程:dp[i] = dp[i-1] + dp[i-2]。 (对于爬到第 i 级,可以从 i-1 级楼梯爬过来,也可以从 i-2 级楼梯爬过来)
- 状态数:O(n)
- 状态转移消耗:O(1)
- 时间复杂度:O(n)
class Solution { public:int climbStairs(int n) {vector<int> dp(n+1);dp[0] = dp[1] = 1;for (int i = 2; i < dp.size(); i++)dp[i] = dp[i - 1] + dp[i - 2];return dp[n];} };
2、最大子数组和(最大子段和)
- 问题描述:给定一个 n 个元素的数组 arr[],求一个子数组,并且它的元素和最大,返回最大的和。
- 状态:dp[i] 表示以第 i 个元素结尾的最大子数组和。
- 初始状态:dp[0] = arr[0](可以为负数)
- 状态转移方程:dp[i] = arr[i] + max(dp[i-1], 0)。 (因为是以第i个元素结尾,所以 arr[i]必选, dp[i-1] 这部分是以第 i-1 个元素结尾的,可以不选或者选,完全取决于它是否大于0,所以选和不选取大者)
- 状态数:O(n)
- 状态转移消耗:O(1)
- 时间复杂度:O(n)
class Solution {
public:int maxSubArray(vector<int>& arr) {vector<int> dp(arr.size()+1);dp[0] = arr[0];int maxSum=dp[0];for(int i=1;i<arr.size();i++){dp[i] = arr[i] + max(dp[i-1], 0);maxSum = max(maxSum, dp[i]);}return maxSum;}
};还有一个双O(1)的方法
class Solution {
public:int maxSubArray(vector<int>& arr) {if (arr.empty()) return 0;int currentSum = arr[0];int maxSum = arr[0];for (int i = 1; i < arr.size(); ++i) {currentSum = max(currentSum + arr[i], arr[i]);maxSum = max(maxSum, currentSum);}return maxSum;}
};
3、最长递增子序列
- 问题描述:给定一个 n 个元素的数组 arr[],求一个最大的子序列的长度,序列中元素单调递增。
- 状态:dp[i] 表示以第 i 个元素结尾的最长递增子序列的长度。
- 初始状态:dp[0] = 1
- 状态转移方程:dp[i] = max(dp[i], dp[j] + 1)。(arr[j] < arr[i]) (对于所有下标比 i 小的下标 j,并且满足 arr[j] < arr[i] 的情况,取所有这里面 dp[j] 的最大值 加上 1 就是 dp[i] 的值,当然可能不存在这样的 j,那么这时候 dp[i] 的值就是 1)
- 状态数:O(n)
- 状态转移消耗:O(n)
- 时间复杂度:O(n^2)
class Solution {
public:int lengthOfLIS(vector<int>& nums) {vector<int> dp(nums.size(), 1);int maxlength = 1;for (int i = 1; i < nums.size(); i++) {for (int j = 0; j < i; j++) {if (nums[j] < nums[i]) {dp[i] = max(dp[i], dp[j] + 1);maxlength = max(maxlength, dp[i]);}}}return maxlength;}
};
4、数字三角形
- 问题描述:给定一个 n 行的三角形 triangle[][],找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 i 或 i + 1。
- 状态:dp[i][j] 表示从顶部走到 (i, j) 位置的最小路径和。
- 初始状态:dp[0][0] = triangle[0][0];起点就是顶部,路径和只能是它自己。
- 状态转移方程:dp[i][j] = max(dp[i-1][j-1], dp[i-1][j]) + triangle[i][j]。(走到
(i,j)
的路径只能从两个方向来:从左上方来(即从(i-1, j-1)
走到(i,j)
)从上方来(即从(i-1, j)
走到(i,j)
)所以我们只需要比较这两个方向的最小值,加上当前位置的值即可。) - 状态数:O(n^2)
- 状态转移消耗:O(1)
- 时间复杂度:O(n^2)
class Solution {
public:int minimumTotal(vector<vector<int>>& triangle) {int n = triangle.size();vector<vector<int>> dp(n, vector<int>(n, 0));int minsum = 0;dp[0][0] = triangle[0][0];for (int i = 1; i < triangle.size(); i++) {for (int j = 0; j < triangle[i].size(); j++) {if (j == 0)dp[i][j] = dp[i - 1][j] + triangle[i][j];else if (j == i)dp[i][j] = dp[i - 1][j - 1] + triangle[i][j];elsedp[i][j] =min(dp[i - 1][j - 1], dp[i - 1][j]) + triangle[i][j];}}return *min_element(dp[n - 1].begin(), dp[n - 1].end());}
};
5、股票系列
力扣有一些非常经典的股票问题,可以自己尝试去看一下。
121. 买卖股票的最佳时机这个解法不是dp
class Solution {
public:int maxProfit(vector<int>& prices) {int cost = INT_MAX, profit = 0;for (int price : prices) {cost = min(cost, price);profit = max(profit, price - cost);}return profit;}
};
122. 买卖股票的最佳时机 II
你需要在每一天决定是否 买、卖、或不操作 股票,最终获得 最大利润 。
限制条件: 任何时候最多只能持有一股股票(即必须先卖出才能再买)。
我们每天的状态只有两种可能:
- 状态 0: 手里没有股票(可以买)
- 状态 1: 手里有股票(可以卖)
我们用一个二维数组 dp[i][0]
和 dp[i][1]
来记录第 i
天结束后,这两种状态下的 最大利润 。
从第 i-1 天的状态推导第 i 天的状态
(1) 当前状态 0(手里没有股票)
- 可能来源:
- 昨天也没股票(今天没买),利润不变:
dp[i-1][0]
- 昨天有股票(今天卖了),利润 = 昨天有股票的利润 + 今天卖出的价格:
dp[i-1][1] + prices[i]
- 昨天也没股票(今天没买),利润不变:
- 取最大值:dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i])
(2) 当前状态 1(手里有股票)
- 可能来源:
- 昨天也有股票(今天没卖),利润不变:
dp[i-1][1]
- 昨天没股票(今天买了),利润 = 昨天没股票的利润 - 今天买入的价格:
dp[i-1][0] - prices[i]
- 昨天也有股票(今天没卖),利润不变:
- 取最大值:dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])
4. 初始状态
- 第 0 天(第一天):
dp[0][0] = 0
(没有买,利润为 0)dp[0][1] = -prices[0]
(买了,但还没卖,利润为负)
5. 最终答案
最后一天 不持有股票 的利润一定是最大的(因为持有股票还没卖的话,利润可能不是最大):return dp[n-1][0] // n 是天数
class Solution {
public:int maxProfit(vector<int>& prices) {int n = prices.size();vector<vector<int>> dp(n, vector<int>(2, 0));// 初始状态dp[0][0] = 0;dp[0][1] = -prices[0];for (int i = 1; i < n; ++i) {dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i]);dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i]);}return dp[n-1][0]; // 返回最后一天不持有股票的最大利润}
};
123. 买卖股票的最佳时机 III
class Solution {
public:int maxProfit(vector<int>& prices) {int n = prices.size();vector<vector<int>> dp(n, vector<int>(4));dp[0][0] = -prices[0], dp[0][1] = 0, dp[0][2] = -prices[0],dp[0][3] = 0;for (int i = 1; i < n; i++) {dp[i][0] = max(-prices[i], dp[i - 1][0]);dp[i][1] = max(dp[i - 1][0] + prices[i], dp[i - 1][1]);dp[i][2] = max(dp[i - 1][1] - prices[i], dp[i - 1][2]);dp[i][3] = max(dp[i - 1][2] + prices[i], dp[i - 1][3]);}return max(dp[n - 1][1], dp[n - 1][3]);}
};
188. 买卖股票的最佳时机 IV
fucking-algorithm/动态规划系列/团灭股票问题.md at master · labuladong/fucking-algorithm
309. 买卖股票的最佳时机含冷冻期
714. 买卖股票的最佳时机含手续费
6、最短路径问题
Dijkstra 本质也是一个动态规划问题。只不过通过不断更新状态,来实现状态转移。
7、背包问题
0/1背包DP
完全背包DP
三、细节剖析
1、问题求什么,状态就尽量定义成什么,有了状态,再去尽力套状态转移方程。
2、动态规划的时间复杂度等于 状态数 x 状态转移 的消耗;
3、状态转移方程中的 i 变量导致数组下标越界,从而可以确定哪些状态是初始状态;
4、状态转移的过程一定是单向的,把每个状态理解成一个结点,状态转移理解成边,动态规划的求解就是在一个有向无环图上进行递推计算。
5、因为动态规划的状态图是一个有向无环图,所以一般会和拓扑排序联系起来。
题目
接龙数列
数组切分
最大魅力值
0、自然语言视频题解
- 接龙数列
- 数组切分
- 最大魅力值
3、C++视频题解
- 接龙数列
- 数组切分
- 最大魅力值
使用最小花费爬楼梯
打家劫舍
删除并获得点数
买卖股票的最佳时机(带字幕版)
递推
斐波那契数
第 N 个泰波那契数
剑指 Offer 10- II. 青蛙跳台阶问题
三步问题
剑指 Offer 10- I. 斐波那契数列
爬楼梯
剑指 Offer II 003. 前 n 个数字二进制中 1 的个数
旋转函数
访问完所有房间的第一天
线性DP / 状态转移 O(C)
使用最小花费爬楼梯
剑指 Offer II 088. 爬楼梯的最少成本
解决智力问题
打家劫舍
剑指 Offer II 089. 房屋偷盗
按摩师
打家劫舍 II
剑指 Offer II 090. 环形房屋偷盗
剑指 Offer 46. 把数字翻译成字符串
解码方法
1 比特与 2 比特字符
使序列递增的最小交换次数
恢复数组
秋叶收藏集
删除并获得点数
完成比赛的最少时间
线性DP / 状态转移 O(n)
单词拆分
分隔数组以得到最大和
最低票价
跳跃游戏 II
带因子的二叉树
最大子数组和
剑指 Offer 42. 连续子数组的最大和
连续数列
最大子数组和
任意子数组和的绝对值的最大值
乘积最大子数组
乘积为正数的最长子数组长度
删除一次得到子数组最大和
最长递增子序列
最长数对链
最长递增子序列的个数
摆动序列
最长湍流子数组
最长递增子序列
最长字符串链
堆箱子
俄罗斯套娃信封问题
马戏团人塔
使数组 K 递增的最少操作次数
股票问题
股票平滑下跌阶段的数目
买卖股票的最佳时机 II
买卖股票的最佳时机含手续费
最佳买卖股票时机含冷冻期
买卖股票的最佳时机 III
前缀最值
有效的山脉数组
将每个元素替换为右侧最大元素
买卖股票的最佳时机
最佳观光组合
数组中的最长山脉
适合打劫银行的日子
两个最好的不重叠活动
接雨水
移除所有载有违禁货物车厢所需的最少时间
接雨水 II
前缀和
分割字符串的最大得分
哪种连续子字符串更长
翻转字符
将字符串翻转到单调递增
删掉一个元素以后全为 1 的最长子数组
和为奇数的子数组数目
两个非重叠子数组的最大和
K 次串联后最大子数组之和
找两个和为目标值且不重叠的子数组
生成平衡数组的方案数
三个无重叠子数组的最大和
统计特殊子序列的数目
相关文章:
线性DP(动态规划)
线性DP的概念(视频) 学习线性DP之前,请确保已经对递推有所了解。 一、概念 1、动态规划 不要去看网上的各种概念,什么无后效性,什么空间换时间,会越看越晕。从做题的角度去理解就好了,动态规划…...
Qt中实现工厂模式
在Qt中实现工厂模式可以通过多种方式,具体选择取决于需求和场景。以下是几种常见的实现方法: 1. 简单工厂模式通过一个工厂类根据参数创建不同对象。cppclass Shape {public: virtual void draw() 0; virtual ~Shape() default;};class Circle : publ…...
基于 Dify + vLLM插件 + Qwen3 构建问答机器人Docker版
前提条件 硬件要求: 推荐 NVIDIA GPU (至少 16GB 显存,Qwen3 可能需要更多) 至少 32GB 内存 足够的存储空间 (Qwen3 模型文件较大) 软件要求: Docker 和 Docker Compose Python 3.8 CUDA 和 cuDNN (与你的 GPU 兼容的版本) 安装步骤…...
【Linux】Linux应用开发小经验
基于Petalinux工具链的Linux应用开发小经验,未完待续... 部分图片和经验来源于网络,若有侵权麻烦联系我删除,主要是做笔记的时候忘记写来源了,做完笔记很久才写博客。 专栏目录:记录自己的嵌入式学习之路-CSDN博客 目录…...
第39课 绘制原理图——绘制命令在哪里?
绘制原理图符号的命令在哪里? 在新建完原理图之后,我们就可以在原理图上绘制各种相关的符号了。 我们基本会从以下的两个地方,找到绘制各种符号的命令: 菜单栏中的“放置”菜单; 悬浮于设计窗口中的快速工具条 在初…...
第十四篇:系统分析师第三遍——15章
目录 一、目标二、计划三、完成情况四、意外之喜(最少2点)1.计划内的明确认知和思想的提升标志2.计划外的具体事情提升内容和标志 五、总结六、后面准备怎么做? 一、目标 通过参加考试,训练学习能力,而非单纯以拿证为目的。 1.在复习过程中&…...
市面上所有大模型apikey获取指南(持续更新中)
阿里云(千问) 官方文档: 百炼控制台 1. 登录百炼控制台 2.前往我的api页面百炼控制台 3.创建api4. 添加描述(用于aichat) Deepseek 官方文档:首次调用 API | DeepSeek API Docs 1. 登录api平台 DeepSeek 开放平台 2. Deep…...
Java框架“若依RuoYi”前后端分离部署
运行环境 Eclipse IDE for Enterprise Java and Web Developers 下载Eclipse解压Eclipse到文件夹 Maven 下载Maven解压Maven到文件夹配置环境变量MAVEN_HOME为Maven安装位置配置环境变量path为%MAVEN_HOME%\bin Redis 下载Redis解压Redis到文件夹配置环境变量path为Redis安装位…...
计网_可靠传输ARQ机制
2024.09.04:网工老姜&beokayy网工学习笔记 第5节 可靠传输机制 5.1 可靠传输5.2 ARQ机制、ARQ协议5.3 ARQ简介(可靠传输)5.3.1 停止等待协议(1)无差错情况(2)有差错情况确认丢失确认迟到 5.…...
实验-组合电路设计1-全加器和加法器(数字逻辑)
目录 一、实验内容 二、实验步骤 2.1 全加器的设计 2.2 加法器的设计 三、调试过程 3.1 全加器调试过程 2.加法器的调试过程 四、实验使用环境 五、实验小结和思考 一、实验内容 a) 介绍 在这次实验中,你将熟悉 Logisim 的操作流程,并且学习…...
软件管理(安装方式)
1.rpm安装 1.1.rpm介绍 rpm软件包名称: 软件名称 版本号(主版本、次版本、修订号) 操作系统 -----90%的规律 举例:openssh-6.6.1p1-31.el7.x86_64.rpm 数字是版本号:第一位主版本号,第二位次版本号,带横杠的是修订号, el几---操作系统的版本。 #用rpm安装需要考虑如下信…...
工作记录 2015-07-15
工作记录 2015-07-15 序号 工作 相关人员 1 在CDAEditor上增加签名的处理,已经基本改完。明天整理说明文档,更新193服务器。 郝 需要改了签名的处理 增加了签名的按钮: 已经签名过的会有提示: 签名后PDF的预览如下…...
《算法导论(第4版)》阅读笔记:p4-p5
《算法导论(第4版)》学习第 3 天,p4-p5 总结,总计 2 页。 一、技术总结 1.instance Thus, given the input sequence h31; 41; 59; 26; 41; 58i, a correct sorting algorithm returns as output the sequence h26; 31; 41; 41; 58; 59i. Such an inp…...
【Mytais系列】Update语句执行流程
以下是通过 时序图 和 文字说明 详细描述的 MyBatis 执行 UPDATE/INSERT/DELETE 语句的完整流程,包括缓存清理、事务提交和数据库操作的各个环节: 时序图(Sequence Diagram) 详细执行流程解析 1. 客户端发起更新请求 客户端调用…...
LeetCode —— 145. 二叉树的后序遍历
😶🌫️😶🌫️😶🌫️😶🌫️Take your time ! 😶🌫️😶🌫️😶🌫️😶🌫️…...
Python函数参数机制深度解析与最佳实践
引言 在Python开发中,函数的参数机制是构建灵活、可维护代码的核心要素。本文将通过7个关键维度深入剖析函数参数的底层原理与高级用法,结合代码实例揭示参数传递的本质规律,助您掌握工业级函数设计技巧(基于Python 3.12环境验证…...
ARM 算数指令
加法 ADD 减法 SUB 取负 NEG 比较 CMP 乘法 MUL 移位 LSL、LSR、ASL、ASR、ROL、ROR加法和减法 绝大多数微处理器都实现了带进位的加法指令,能够将两个操作数和条件码寄存器中的进位位加到一起。这条指令会使字长大于计算机固有字长的链接运算更加方便。 说明了如何…...
普通IT的股票交易成长史--20250502 突破(2)
声明:本文章的内容只是自己学习的总结,不构成投资建议。文中观点基本来自yt站方方土priceaction,综合自己的观点得出。感谢他们的无私分享。 送给自己的话: 仓位就是生命,绝对不能满仓!!&#…...
什么是 Redis?
什么是 Redis? Redis(全称是 Remote Dictionary Server,远程字典服务器)是一个非常快的开源内存数据库,它主要用来存储“键-值”对类型的数据。与传统的数据库不太一样,Redis的数据主要存放在内存中,所以它读写速度特别快。 通俗比喻: 想象你有一个小仓库,里面放了…...
IEEE LaTeX会议模板作者对齐、部门长名称换行
第二行作者对齐 参考链接: https://tex.stackexchange.com/questions/458204/ieeetran-document-class-how-to-align-five-authors-properly/458208#458208https://tex.stackexchange.com/questions/582487/how-to-align-four-author-names-in-the-ieee-conferenc…...
前端面经-VUE3篇(二)--vue3组件知识(二)依赖注入、异步组件、生命周期、组合式函数、插件
目录 一、依赖注入 1、 依赖注入是什么? 2、最基础的使用 3、为什么使用依赖注入? 4、 使用 Symbol 作注入名 二、异步组件 1、什么是异步组件? 2、最基础用法:defineAsyncComponent 3、在模板中使用异步组件 4、配置加载状态…...
Manus联合创始人:公司产品基于Claude和阿里千问大模型开发
3月11日消息,日前,Manus官方在社交平台转发了公司联合创始人、首席科学家季逸超对Manus的技术解读,季逸超在评论区回复网友关于“Manus使用了哪一个基础大模型”这一问题时回复称,“我们用过Claude,也用过不同版本的Qw…...
华为云Flexus+DeepSeek征文|快速搭建Dify LLM应用开发平台教程
目录 部署Dify-LLM应用开发平台开始使用一键卸载注意事项 部署Dify-LLM应用开发平台 1、首先需要访问快速搭建Dify-LLM应用开发平台-华为云 2、使用"一键部署"功能快速搭建Dify平台快速搭建Dify LLM应用开发平台-云社区-华为云,本文在这里选择一键部署&…...
简介QML中的Canvas
2025年5月3日,周六晚上 QML中的Canvas是一个强大的绘图组件,允许开发者通过JavaScript在界面上进行动态的2D图形绘制。它类似于HTML5的<canvas>元素,适用于实现自定义图形、动画、游戏开发以及图表绘制等场景。 核心特性 绘图能力 • …...
装饰器@wraps(func)详解
1. wraps(func) 的核心作用 wraps 是 Python 标准库 functools 提供的装饰器,用于保留被装饰函数的原始元信息。 它通过将原函数的 __name__、__doc__、__module__ 等属性复制到装饰器内部的包装函数中,避免装饰器对函数身份信息的“掩盖”。 2. 元信息…...
vue的diff算法是什么、比较方式,原理分析、示例解释讲解
Vue Diff算法概述 Vue 的 Diff 算法是一种高效的虚拟 DOM 更新机制,用于最小化真实 DOM 的操作开销。它通过比较新旧 Virtual DOM 树中的差异,仅更新那些实际发生改变的部分,从而提升性能。 定义 Diff 算法的核心目标是在 MVVM 开发模式下…...
Day04 新增套餐
###今天的任务主要是自主完成套餐管理的模块### 1.新增套餐 在前端页面接口中我们可以看到在新增套餐的时候需要选择添加到菜单中的菜品 因此我们需要设计一个接口可以通过根据分类id(category_id)来查询该分类下的菜品 1.1根据分类id查询分类下的菜…...
WEB前端小练习——记事本
一、登陆页面 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>记事本登录注册</title><link…...
在多线程环境下如何设计共享数据结构保证原子操作与数据一致性
在多线程环境下如何设计共享数据结构保证原子操作与数据一致性 1. 引言 在现代软件开发中,多线程编程是提升程序性能和响应速度的重要手段。然而,多线程环境下的 共享数据管理 极具挑战性,若处理不当,可能引发 竞争条件(Race Conditions)、数据不一致(Data Inconsiste…...
洛谷 P1850 [NOIP 2016 提高组] 换教室
题目传送门 前言 终于自己想出概率期望 d p dp dp 的状态了,但是依旧没能相对转移方程。(招笑) 暴力 这题部分分和特殊情况分给的挺多的,所以先拿部分分。 一、思路 先跑一边 F l o y d Floyd Floyd 最短路求出两点间最短距…...
1penl配置
好的,根据您提供的 1pctl 命令输出信息,我们来重新依次回答您的所有问题: 第一:1Panel 怎么设置 IP 地址? 根据您提供的 user-info 输出: 面板地址: http://$LOCAL_IP:34523/93d8d2d705 这里的 $LOCAL_I…...
Windows下调试WebRTC源码
一、引言 《Windows下编译WebRTC源码》讲述了Windows下编译WebRTC源码的方法。本文在其基础之上,讲述使用Visual Studio调试WebRTC源码的方法。 二、生成Visual Studio工程文件 按照 《Windows下编译WebRTC源码》编译出webrtc.lib 后,执行下面的命令生…...
基于大模型的肾结石诊疗全流程风险预测与方案制定研究报告
目录 一、引言 1.1 研究背景与意义 1.2 国内外研究现状 1.3 研究目标与内容 二、大模型技术原理与应用概述 2.1 大模型的基本原理 2.2 大模型在医疗领域的应用进展 2.3 适用于肾结石预测的大模型选择与依据 三、术前风险预测与准备 3.1 患者身体状况评估 3.2 结石情…...
《ATPL地面培训教材13:飞行原理》——第5章:升力
翻译:刘远贺;工具:Cursor & Claude 3.7;过程稿 第5章:升力 目录 空气动力系数基本升力方程回顾升力曲线升力曲线的解释速度-动压关系密度高度翼型剖面升力特性阻力特性简介升阻比飞机重量对最小飞行速度的影响表…...
STM32部分:2、环境搭建
飞书文档https://x509p6c8to.feishu.cn/wiki/DQsBw76bCiWaO4kS8TXcWDs0nAh Keil MDK用于编写代码,编译代码芯片支持包,用于支持某类芯片编程支持STM32CubeMX用于自动生成工程,减少手动重复工作 STM32F1系列芯片支持包 软件下载 直接下载&am…...
STL之list容器
list的介绍 1.list的底层是双向链表结构,双向链表中的每个元素在互不相关的独立结点中,在结点中通过指针指向前一个元素和后一个元素 2.list是可以在常数范围内在任意位置的插入和删除的序列式容器,并且该容器可以前后双向迭代 3.vector的…...
DNS 域名解析
DNS(Domain Name System) 是一个将域名转换为IP地址的系统。它的主要功能是使用户能够通过易于记忆的域名访问互联网资源,而不是记住复杂的IP地址。DNS类似于“互联网的电话簿”,帮助计算机找到彼此的位置。 一、DNS的基本概念 …...
我写了一个分析 Linux 平台打开文件描述符跨进程传递的工具
Linux 系统的设计中,继承了 Unix “一切皆文件” (Everything is a file) 的思想,系统中的众多对象,都可以表示为文件,可以对它们执行文件操作,如 read()、write()、mmap()、ioctl()、close() 和 poll() 等。Linux 系统…...
QML图像提供器 (Image Provider)
QML 中的图像提供器是一种自定义图像加载机制,允许你从非文件源(如数据库、网络或程序生成的内容)提供图像数据。 主要类型 QQuickImageProvider - 基础图像提供器 QPixmapImageProvider - 提供 QPixmap 图像 QImageImageProvider - 提供 …...
【Java学习】通配符?
面向对象系列八:泛型(二) 一、通配符? 二、泛型符<> 1.泛型类里 2.泛型类外 2.1使用过程中 2.2使用最后末 三、限制 1.泛型类里的限制 2.延申处的限制 2.1extend限制上界 2.1.1返回值接 2.1.2形参传 2.2super限制下界 2.2.1形参传 2.2.2返回值…...
安卓基础(悬浮窗和摄像)
ACTION_MANAGE_OVERLAY_PERMISSION 的作用就是 打开系统设置的「悬浮窗权限管理页面」 Intent intent new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,Uri.parse("package:" getPackageName()) ); startActivity(intent); 直接跳转目标应用的权限…...
一种实波束前视扫描雷达目标二维定位方法——论文阅读
一种实波束前视扫描雷达目标二维定位方法 1. 专利的研究目标与实际问题意义2. 专利提出的新方法、模型与公式2.1 运动平台几何建模与回波信号构建2.1.1 距离历史建模2.1.2 回波信号模型2.2 距离向运动补偿技术2.2.1 匹配滤波与距离压缩2.3 加权最小二乘目标函数2.3.1 方位向信号…...
基于springboot的金院银行厅预约系统的设计及实现(源码+lw+部署文档+讲解),源码可白嫖!
摘要 随着信息技术在管理上越来越深入而广泛的应用,信息管理系统的实施在技术上已逐步成熟。信息管理系统是一个不断发展的新型学科,任何一个单位要生存要发展,要高效率地把内部活动有机地组织起来,就必须建立与自身特点相适应的…...
AVFormatContext 再分析零
随着对于AVFormatContext 各个参数的学习,逐渐可以从 整体架构上 再认识一下 AVFormatContext 了。 还是从解封装的第一步开始。 int avformat_open_input(AVFormatContext **ps, const char *url, ff_const59 AVInputFormat *fmt, AVDictionary **options); 实际上…...
【学习心得】魔塔(ModelScope)和抱抱脸(Hugging Face)下载模型小细节
介绍常用的两种在模型社区如魔塔(ModelScope)和抱抱脸(Hugging Face),下载预训练模型的方法,然后说明各种方法里面的小细节。 一、SDK下载 对于希望直接通过编程方式集成模型下载功能到自己的项目中的开发…...
嵌入式硬件篇---STM32 系列单片机型号命名规则
文章目录 前言一、STM32 型号命名规则二、具体型号解析1. STM32F103C8T6F103:C:8:T6:典型应用2. STM32F103RCT6F103:R:C:T6:典型应用三、命名规则扩展1. 引脚数与封装代码2. Flash 容量代码3. 温度范围代码四、快速识别技巧性能定位:F1/F4后缀差异硬件设计参考:引脚数…...
关于算法设计与分析——拆分表交换问题
题目: 用蛮力法设计一个算法,将A{a1, a2, ..., an}拆成B和C两个表,使A中值大于等于0的元素存入表B,值小于0的元素存入表C,要求表B和C不另外设置存储空间而利用表A的空间。 1)问题分析 题目要求设计一个算…...
在pycharm profession 2020.3上离线安装.whl类型的包(以PySimpleGUI为例)
今天写个小代码,用到了PySimpleGUI。 在pycharm profession 2020.3的项目中的Terminal里运行如下代码即可安装。 python3 -m pip install --force-reinstall --extra-index-url https://PySimpleGUI.net/install PySimpleGUI 安装方法如图: 安装后使用…...
c++回调函数
函数指针 //函数 bool lengthCompare(const string&, const string&); //pf为指针,指向一个函数,函数的类型为:bool (const string&, const string&) bool (*pf)(const string&, const string&); //函数࿰…...
mysql主从复制搭建,并基于Keepalived + VIP实现高可用
以下是基于 Keepalived VIP 实现 MySQL 主从复制高可用的详细步骤,涵盖主从复制搭建与故障自动切换: 一、MySQL 主从复制搭建(基础步骤回顾) 1. 主库(Master)配置 修改配置文件 /etc/my.cnf&…...