这是一份动态规划(Dynamic Programming, DP)完整学习笔记。笔记将从一星难度(入门)到五星难度(进阶),循序渐进,涵盖核心思想、经典模型和解题方法论。
本来打算今天更新背包问题的题解的,但事情比较多,就拿一篇笔记来更新吧+_+


动态规划核心思想 (Pre-Star)

在开始之前,我们必须理解动态规划的本质。它不是一种特定的算法,而是一种解决问题的思想

  1. 什么是动态规划?

动态规划是一种将复杂问题分解成更小的、可重复的子问题,并通过存储子问题的解来避免重复计算,从而找到原问题最优解的方法。

2. DP 的两个核心特征:

  • 最优子结构 (Optimal Substructure): 原问题的最优解可以由其子问题的最优解构成。这意味着我们可以通过组合子问题的最优解,来得到原问题的最优解。

  • 重叠子问题 (Overlapping Subproblems): 在问题的求解过程中,许多子问题会被多次重复计算。DP 的高效正体现在它只需计算一次,然后将结果存起来供后续使用。

3. 解题的两种主要实现方式:

  • 自顶向下 (Top-Down) 与记忆化搜索: 从原问题出发,通过递归函数求解。如果遇到已经计算过的子问题,直接返回存储的结果,否则进行计算并存入备忘录。

  • 自底向上 (Bottom-Up) 与递推: 从最小的子问题开始,迭代地计算并填充 DP 表,直到计算出原问题的解。这是更常见、通常也更高效的实现方式。

  1. 动态规划解题五步法 (非常重要!)

几乎所有的 DP 问题都可以套用以下五个步骤来思考:

  1. 定义 dp 数组的含义: 这是最关键的一步。明确 dp[i]dp[i][j] 代表什么,比如 dp[i] 是前 i 个元素能获得的最大价值。

  2. 找出递推关系式(状态转移方程): 这是 DP 的核心。思考 dp[i] 是如何由之前的状态(如 dp[i-1], dp[i-2] 等)推导出来的。

  3. 初始化 dp 数组: 根据递推公式和 dp 数组的定义,设置好初始值(base case),比如 dp[0] 的值。

  4. 确定遍历顺序: 思考是应该从前向后遍历,还是从后向前,或者二维数组的内外层循环顺序。这取决于状态转移方程中 dp[i] 依赖于哪些历史状态。

  5. 根据 dp 数组推导出最终解: 最终答案可能直接是 dp 数组的某个值,也可能是整个数组的最大值。


★☆☆☆☆ (一星): 线性 DP 入门

这个阶段主要是理解 DP 的基本思想,通常处理一维数组或序列问题。

经典问题1:斐波那契数列 / 爬楼梯
  • 问题描述 (爬楼梯): 你在爬一个 n 阶的楼梯。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶?

  • 五步法分析:

    1. dp 定义: dp[i] 表示爬到第 i 阶楼梯的不同方法数。

    2. 递推公式: 要到达第 i 阶,可以从第 i-1 阶爬 1 步上来,也可以从第 i-2 阶爬 2 步上来。所以 dp[i] = dp[i-1] + dp[i-2]

    3. 初始化: dp[1] = 1 (爬到第1阶只有1种方法),dp[2] = 2 (可以 1+1 或 2)。

    4. 遍历顺序:i = 3n,从前向后遍历。

    5. 最终解: dp[n]

  • 代码示例 (C++):

    int climbStairs(int n) {if (n <= 2) return n;std::vector<int> dp(n + 1);dp[1] = 1;dp[2] = 2;for (int i = 3; i <= n; ++i) {dp[i] = dp[i - 1] + dp[i - 2];}return dp[n];}
经典问题2:打家劫舍 (House Robber I)
  • 问题描述: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,但相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。

  • 五步法分析:

    1. dp 定义: dp[i] 表示偷窃前 i 间房屋所能获得的最大金额。

    2. 递推公式: 对于第 i 间房,你有两个选择:

      • 不偷第 i 间: 最大金额等于偷前 i-1 间的最大金额,即 dp[i-1]

      • 偷第 i 间: 那么第 i-1 间就不能偷,最大金额等于偷前 i-2 间的最大金额加上第 i 间的金额,即 dp[i-2] + nums[i-1] (注意 nums 索引)。

      • 取两者最大值:dp[i] = max(dp[i-1], dp[i-2] + nums[i-1])

    3. 初始化: dp[0] = 0 (没有房子),dp[1] = nums[0] (只有一间房,必偷)。

    4. 遍历顺序:i = 2n,从前向后。

    5. 最终解: dp[n]

  • 代码示例 (C++):

    int rob(std::vector<int>& nums) {if (nums.empty()) return 0;int n = nums.size();if (n == 1) return nums[0];std::vector<int> dp(n + 1);dp[0] = 0;dp[1] = nums[0];for (int i = 2; i <= n; ++i) {dp[i] = std::max(dp[i - 1], dp[i - 2] + nums[i - 1]);}return dp[n];}

★★☆☆☆ (二星): 二维 DP 与经典模型

这个阶段开始引入二维 dp 数组,用于解决需要两个变量来定义状态的问题。背包问题是这个阶段的重中之重。

经典问题1:不同路径 (Unique Paths)
  • 问题描述: 一个机器人在一个 m x n 网格的左上角,它每次只能向右或者向下移动一步。机器人试图达到网格的右下角。问总共有多少条不同的路径?

  • 五步法分析:

    1. dp 定义: dp[i][j] 表示从左上角到达坐标 (i, j) 的路径数。

    2. 递推公式: 要到达 (i, j),只能从 (i-1, j) (上面) 或 (i, j-1) (左面) 过来。所以 dp[i][j] = dp[i-1][j] + dp[i][j-1]

    3. 初始化: 第一行和第一列的所有格子都只有一条路径到达,所以 dp[i][0] = 1dp[0][j] = 1

    4. 遍历顺序: 从上到下,从左到右。

    5. 最终解: dp[m-1][n-1]

  • 代码示例 (C++):

    int uniquePaths(int m, int n) {std::vector<std::vector<int>> dp(m, std::vector<int>(n, 0));for (int i = 0; i < m; ++i) dp[i][0] = 1;for (int j = 0; j < n; ++j) dp[0][j] = 1;for (int i = 1; i < m; ++i) {for (int j = 1; j < n; ++j) {dp[i][j] = dp[i - 1][j] + dp[i][j - 1];}}return dp[m - 1][n - 1];}
经典问题2:0-1 背包问题
  • 问题描述:N 件物品和一个容量为 V 的背包。第 i 件物品的重量是 weight[i],价值是 value[i]。求解将哪些物品装入背包,可使这些物品的重量总和不超过背包容量,且价值总和最大。

  • 五步法分析 (二维数组版本):

    1. dp 定义: dp[i][j] 表示从前 i 件物品中任意选择,放入容量为 j 的背包中,所能获得的最大价值。

    2. 递推公式: 对于第 i 件物品,有两个选择:

      • 不放入背包: 最大价值等于只考虑前 i-1 件物品放入容量 j 的背包,即 dp[i-1][j]

      • 放入背包: (前提是 j >= weight[i]),价值等于只考虑前 i-1 件物品放入容量为 j - weight[i] 的背包的最大价值,再加上第 i 件物品的价值,即 dp[i-1][j - weight[i]] + value[i]

      • 取两者最大值:dp[i][j] = max(dp[i-1][j], dp[i-1][j - weight[i]] + value[i])

    3. 初始化: dp[0][j] = 0 (不选任何物品,价值为0)。dp[i][0] = 0 (背包容量为0,价值为0)。

    4. 遍历顺序: 外层循环物品 i 从 1到 N,内层循环背包容量 j 从 1 到 V。

    5. 最终解: dp[N][V]

  • 代码示例 (C++,空间优化后的一维数组版本):

    一维数组优化是背包问题的精髓。

    1. dp 定义: dp[j] 表示容量为 j 的背包所能获得的最大价值。

    2. 递推公式: dp[j] = max(dp[j], dp[j - weight[i]] + value[i])

    3. 初始化: dp 数组全部初始化为 0。

    4. 遍历顺序: 外层循环物品 i内层循环容量 j 必须从后向前遍历! 这是为了保证计算 dp[j] 时,所依赖的 dp[j - weight[i]] 还是上一轮 i-1 的状态。

    void test_01_knapsack(int W, int N, const std::vector<int>& weights, const std::vector<int>& values) {std::vector<int> dp(W + 1, 0);for (int i = 0; i < N; ++i) { // 遍历物品for (int j = W; j >= weights[i]; --j) { // 遍历背包容量 (倒序)dp[j] = std::max(dp[j], dp[j - weights[i]] + values[i]);}}std::cout << "Max value is: " << dp[W] << std::endl;}

★★★☆☆ (三星): 序列 DP 与背包变种

这个阶段处理更复杂的序列问题和背包问题的变体,需要更深入的思考状态定义和转移。

经典问题1:最长递增子序列 (Longest Increasing Subsequence)
  • 问题描述: 给定一个整数序列,找到其中最长递增子序列的长度。子序列不要求连续。

  • 五步法分析 (O(N2) 解法):

    1. dp 定义: dp[i] 表示以 nums[i] 结尾的最长递增子序列的长度。

    2. 递推公式: 对于 nums[i],我们需要向前遍历所有 j < i。如果 nums[i] > nums[j],说明 nums[i] 可以接在以 nums[j] 结尾的递增子序列后面,形成一个更长的序列。所以 dp[i] = max(dp[i], dp[j] + 1)

    3. 初始化: dp 数组所有元素都初始化为 1,因为每个元素自身都构成一个长度为 1 的递增子序列。

    4. 遍历顺序: 外层循环 i 从 0 到 n-1,内层循环 j 从 0 到 i-1

    5. 最终解: 最终答案是整个 dp 数组中的最大值,而不是 dp[n-1]

  • 代码示例 (C++):

    int lengthOfLIS(std::vector<int>& nums) {if (nums.empty()) return 0;int n = nums.size();std::vector<int> dp(n, 1);int max_len = 1;for (int i = 1; i < n; ++i) {for (int j = 0; j < i; ++j) {if (nums[i] > nums[j]) {dp[i] = std::max(dp[i], dp[j] + 1);}}max_len = std::max(max_len, dp[i]);}return max_len;}
_注:此问题有更优的 O(NlogN) 解法,使用贪心+二分查找,属于进阶内容。_
经典问题2:完全背包 (Unbounded Knapsack)
  • 问题描述: 与 0-1 背包类似,但每种物品可以无限次地放入背包。

  • 分析: 与 0-1 背包唯一的区别在于,当你考虑第 i 件物品时,你还可以继续考虑它。这体现在一维 dp 数组的遍历顺序上。

  • 遍历顺序变化: 内层循环容量 j 从前向后遍历。

    • 为什么? 在计算 dp[j] 时,我们需要用到 dp[j - weight[i]] 的值。在正序遍历中,dp[j - weight[i]] 已经被本轮(第i件物品)更新过,这等价于第 i 件物品已经被放入过一次,可以再次放入。
  • 代码示例 (C++):

    void test_unbounded_knapsack(int W, int N, const std::vector<int>& weights, const std::vector<int>& values) {std::vector<int> dp(W + 1, 0);for (int i = 0; i < N; ++i) { // 遍历物品for (int j = weights[i]; j <= W; ++j) { // 遍历背包容量 (正序)dp[j] = std::max(dp[j], dp[j - weights[i]] + values[i]);}}std::cout << "Max value is: " << dp[W] << std::endl;}

★★★★☆ (四星): 复杂状态与区间 DP

这个阶段的问题状态定义更加复杂,可能包含多个维度,或者需要在一个区间上进行 DP。

经典问题1:股票买卖系列 (Best Time to Buy and Sell Stock)
  • 问题描述: 这是一系列问题,限制了交易次数、引入了冷却期或手续费。我们以最多交易 K 次为例。

  • 五步法分析:

    1. dp 定义: 需要三个维度来定义状态。dp[i][k][s] 表示第 i 天,最多允许 k 次交易,当前持股状态为 s (0:不持股, 1:持股) 时所拥有的最大利润。

    2. 递推公式:

      • dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k][1] + prices[i])

        (今天不持股 = 昨天就不持股,或昨天持股今天卖出)

      • dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i])

        (今天持股 = 昨天就持股,或昨天不持股今天买入。注意买入消耗一次交易,所以是 k-1)

    3. 初始化: dp[-1][k][0] = 0, dp[-1][k][1] = -infinity (还没开始不可能持股)。

    4. 遍历顺序: 天数 i 从 0 到 n-1,交易次数 k 从 1 到 K

    5. 最终解: dp[n-1][K][0] (最后一天不持股的利润一定是最大的)。

  • 这个通用框架可以解决几乎所有的股票问题,只需要根据题意微调状态转移方程即可。

经典问题2:区间 DP (Interval DP)
  • 问题描述 (戳气球):n 个气球,编号为 0 到 n-1,每个气球上都标有一个数字,这些数字存在数组 nums 中。现在要求你戳破所有的气球。每当你戳破一个气球 i 时,你将会获得 nums[left] * nums[i] * nums[right] 个硬币。这里的 leftright 代表和 i 相邻的两个气球的序号。戳破了气球 i 后,leftright 就变成了相邻的气球。求所能获得硬币的最大数量。

  • 分析: 这个问题如果正向思考(先戳哪个),会发现后续状态难以确定。反向思考:最后戳哪个气球?

    1. dp 定义: dp[i][j] 表示戳破区间 (i, j) (开区间) 内所有气球能获得的最大硬币数。

    2. 递推公式: 假设在区间 (i, j) 中,我们最后戳破的气球是 k (i < k < j)。那么此时 ij 就是 k 相邻的气球。戳破 k 的收益是 nums[i] * nums[k] * nums[j]。而在这之前,区间 (i, k)(k, j) 的气球已经被戳破了,这两部分是独立的。所以 dp[i][j] = max(dp[i][k] + dp[k][j] + nums[i] * nums[k] * nums[j]) for k in (i, j)

    3. 初始化: dp 数组初始化为 0。为了方便处理边界,可以在 nums 数组两边各加一个 1。

    4. 遍历顺序: 区间 DP 的遍历顺序很特别。外层循环是区间的长度 len (从 3 到 n),内层循环是区间的起始点 i。这样保证在计算大区间 dp[i][j] 时,所有它依赖的小区间都已经计算完毕。

    5. 最终解: dp[0][n-1] (n是新数组的长度)。


★★★★★ (五星): 状态压缩与树形/图 DP

这是 DP 的最高境界,通常与位运算、图论、树等结构结合,解决 NP-Hard 问题在小规模数据下的最优解。

经典问题1:状态压缩 DP (Bitmask DP)
  • 适用场景: 当问题中某个维度的状态数量不多 (通常 Nle20),且每个状态可以用二进制位来表示(是/否,用过/没用过)时。

  • 问题描述 (旅行商问题 TSP): 给定 n 个城市和一个距离矩阵,求从一个城市出发,访问所有其他城市一次后回到出发点的最短路径。

  • 分析:

    1. dp 定义: dp[mask][i] 表示访问过的城市集合为 mask (一个整数,其二进制表示中第 j 位为 1 代表城市 j 已访问),当前停留在城市 i 时的最短路径长度。

    2. 递推公式: 要从状态 dp[mask][i] 转移,我们可以枚举下一个要去的城市 j。前提是 j 不在 mask 集合中。

      • dp[mask | (1 << j)][j] = min(dp[mask | (1 << j)][j], dp[mask][i] + dist[i][j])
    3. 初始化: dp[1 << start_node][start_node] = 0

    4. 遍历顺序: 外层循环 mask 从 1 到 (1 << n) - 1,中层循环当前城市 i,内层循环下一个城市 j

    5. 最终解: min(dp[(1 << n) - 1][i] + dist[i][start_node]) for all i

经典问题2:树形 DP (Tree DP)
  • 适用场景: 在树形结构上求解最优问题。

  • 问题描述 (打家劫舍 III): 房屋排列成二叉树结构。如果偷窃了某个节点,就不能偷窃其直接相连的子节点。求最大偷窃金额。

  • 分析:

    1. dp 定义: 对于每个节点 u,我们需要知道两个状态:偷它和不偷它能得到的最大收益。所以定义一个 pair 或大小为 2 的数组 dp[u]dp[u][0] 表示不偷 u 时,在以 u 为根的子树中能获得的最大收益。dp[u][1] 表示偷 u 时…

    2. 递推公式 (通过后序遍历/DFS实现):

      • 不偷 u (dp[u][0]): 那么它的左孩子 l 和右孩子 r 都可以偷或不偷,取两者最大值即可。

        dp[u][0] = max(dp[l][0], dp[l][1]) + max(dp[r][0], dp[r][1])

      • 偷 u (dp[u][1]): 那么它的左右孩子都不能偷。

        dp[u][1] = u->val + dp[l][0] + dp[r][0]

    3. 初始化: 递归到叶子节点时,dp[leaf][0] = 0, dp[leaf][1] = leaf->val

    4. 遍历顺序: 使用深度优先搜索(DFS),在回溯时(即后序遍历)进行状态转移。

    5. 最终解: 对于根节点 root,答案是 max(dp[root][0], dp[root][1])


总结与练习建议

  • Practice is Everything: 动态规划是“做”出来的,不是“看”出来的。大量的练习是掌握它的唯一途径。

  • 从模仿开始: 刚开始可以对着题解的思路,自己尝试复现五步法,然后独立写出代码。

  • 画图,画表: 尤其是对于二维 DP,手动填充 DP 表是理解状态转移过程的绝佳方法。

  • 推荐练习平台: LeetCode、AtCoder、Codeforces。LeetCode 上的 DP 题目有很好的分类和难度梯度,非常适合系统性学习。

希望这份笔记能为你打开动态规划的大门!祝你学习愉快!

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

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

相关文章

Linux 可信启动深度解析:从UEFI到操作系统的信任链

文章目录引言一、 可信根基&#xff1a;TPM与核心概念1.1 什么是“度量” (Measurement)&#xff1f;1.2 信任链与TPM PCR二、 阶段一&#xff1a;固件的可信启动 (UEFI)2.1 引导的起点&#xff1a;从SEC到DXE的初始化2.2 引导设备选择 (BDS)&#xff1a;UEFI如何找到GRUB2.3 S…

61-python中面向对象三大特性

前言&#xff1a; 面向对象编程&#xff0c;是许多编程语言都支持的一种编程思想。简单理解是&#xff1a;基于模板&#xff08;类&#xff09;去创建实体&#xff08;对象&#xff09;&#xff0c; 使用对象完成功能开发。面向对象包含三大主要特性&#xff1a; 封装 继承 多态…

BP-Adaboost模型

BP-Adaboost模型是一种将BP神经网络作为弱分类器的集成学习框架&#xff0c;通过AdaBoost算法动态调整样本权重和模型权重&#xff0c;显著提升预测精度和泛化能力。一、模型架构与工作原理 1. 基础框架 弱分类器单元&#xff1a;采用单隐藏层BP神经网络&#xff08;结构示例&a…

k230 +canMV+ LVGL控件 仿手表表盘触摸屏滚动、选中后弹窗效果完整示例程序

现在智能手表用的越来越多,其交互方式比较有特点,现在k230开发板上,基于LVGL(Light and Versatile Graphics Library)编写一个嵌入式GUI应用程序,使用LVGL配合触摸屏实现模仿智能手表的表盘滚动效果,实际效果如下: 程序使用LVGL图形库和MediaManager程序,创建带有触摸…

使用Vue.js和WebSocket打造实时库存仪表盘

大家好&#xff01;今天我将分享一个简单却强大的实时库存仪表盘项目&#xff0c;基于Vue.js和WebSocket技术。这个项目适合初学者学习前端实时数据处理&#xff0c;也能为你的技术博客或作品集增添亮点&#xff01;通过这个教程&#xff0c;你将学会如何使用WebSocket实现实时…

leecode100——接雨水

题目 双指针 思路1 使用参数存储从左往右&#xff08;从右往左同理&#xff09;遍历时的最高的柱子&#xff0c; 然后移动左右的指针&#xff0c;每次移动左右指针中偏向小的&#xff0c; 如果当前指针指的柱子小于最高的柱子&#xff0c;就会存在接到水。 思路2 把水看作柱子&…

复古胶片风格街拍人像Lr调色教程,手机滤镜PS+Lightroom预设下载!

调色教程复古胶片风格街拍人像 Lightroom 调色&#xff0c;通过模拟经典胶片相机的色彩科学&#xff0c;为现代数码照片注入怀旧韵味。这种调色手法注重低饱和度色彩、柔和的高光过渡和丰富的暗部细节&#xff0c;配合适度的颗粒感&#xff0c;营造出时光沉淀的质感。特别适合街…

Linux的gpio子系统

GPIO其实也是某个pin的功能之一。上一小节讲解了 pinctrl 子系统&#xff0c;pinctrl 子系统重点是设置 PIN(有的 SOC 叫做 PAD)的复用和电气属性&#xff0c;如果 pinctrl 子系统将一个 PIN 复用为 GPIO 的话&#xff0c;那么接下来就要用到 gpio 子系统了。gpio 子系统顾名思…

VC++ CPU指令集检测工具实现原理

&#x1f4c8; VC CPU指令集检测工具实现原理 例图&#xff1a;&#x1f9e0; 1. 核心原理&#xff1a;CPUID指令 // 使用CPUID指令获取CPU信息 int cpuInfo[4] { -1 }; __cpuid(cpuInfo, 0); // 调用CPUID指令 int nIds cpuInfo[0]; // 获取最大标准功能号CPUID指令工作流程…

大模型微调理论、实战:LLaMA-Factory、Unsloth

概述 微调&#xff0c;Fine-Tuning&#xff0c;简称FT&#xff0c;可理解为对LLM的定制&#xff0c;目的是增强专业领域知识&#xff0c;并优化特定任务的性能。通过在特定数据集上微调一个预训练模型&#xff0c;可实现&#xff1a; 更新知识&#xff1a;引入新的领域专属信…

【LCA 树上倍增】P9245 [蓝桥杯 2023 省 B] 景区导游|普及+

本文涉及知识点 树上倍增 P9245 [蓝桥杯 2023 省 B] 景区导游 题目描述 某景区一共有 NNN 个景点&#xff0c;编号 111 到 NNN。景点之间共有 N−1N-1N−1 条双向的摆渡车线路相连&#xff0c;形成一棵树状结构。在景点之间往返只能通过这些摆渡车进行&#xff0c;需要花费…

基于Python+Streamlit的旅游数据分析与预测系统:从数据可视化到机器学习预测的完整实现

&#x1f3de;️ 基于PythonStreamlit的旅游数据分析与预测系统&#xff1a;从数据可视化到机器学习预测的完整实现 &#x1f4dd; 前言 在大数据时代&#xff0c;旅游行业的数据分析变得越来越重要。如何从海量的旅游数据中挖掘有价值的信息&#xff0c;并进行准确的销量预测&…

飞算JavaAI全链路实战:智能构建高可用电商系统核心架构

飞算JavaAI全链路实战&#xff1a;智能构建高可用电商系统核心架构 前言&#xff1a;AI编程新时代的电商系统开发范式变革 在当今数字经济时代&#xff0c;电商系统作为企业数字化转型的核心载体&#xff0c;其复杂度和技术要求与日俱增。一个完整的电商系统不仅需要处理商品、…

论文精读(五):面向链接预测的知识图谱表示学习方法综述

笔者链接&#xff1a;扑克中的黑桃A 专栏链接&#xff1a;论文精读 本文关键词&#xff1a;知识图谱; 表示学习; 链接预测; 多元关系; 超关系 引 诸位技术同仁&#xff1a; 本系列将系统精读的方式&#xff0c;深入剖析计算机科学顶级期刊/会议论文&#xff0c;聚焦前沿突破…

Roo Code之自定义指令(Custom Instructions),规则(Rules)

在Roo Code 中&#xff0c;Custom Instructions 可以通过Instructions 设定和Rules 规则文件实现。什么是Custom Instructions&#xff1f; 自定义指令(Custom Instructions)定义了超出Roo基本角色定义范围的具体行为、偏好和约束。示例包括编码风格、文档标准、测试要求和工作…

9/8我是ai大师

一、变量定义部分&#xff08;理解程序的 "记忆"&#xff09;c运行/* USER CODE BEGIN PV */ static uint8_t last_button_state 1; // 初始为高电平&#xff08;未按下&#xff09; static uint8_t device_mode 0; // 设备模式&#xff1a;0LD1, 1LD3, 2蜂鸣器, 3…

前沿重器[74] | 淘宝RecGPT:大模型推荐框架,打破信息茧房

前沿重器栏目主要给大家分享各种大厂、顶会的论文和分享&#xff0c;从中抽取关键精华的部分和大家分享&#xff0c;和大家一起把握前沿技术。具体介绍&#xff1a;仓颉专项&#xff1a;飞机大炮我都会&#xff0c;利器心法我还有。&#xff08;算起来&#xff0c;专项启动已经…

jenkins加docker 部署项目

jenkins加docker 部署springboot项目 1项目结构Dockerfile 内容 FROM openjdk:8-jdk-alpine ARG JAR_FILEtarget/*.jar COPY ${JAR_FILE} app.jar ENTRYPOINT ["java","-jar","/app.jar","--server.port9090"]在A服务器上启动jenkins …

提示词工程(Prompt Engineering)的崛起——为什么“会写Prompt”成了新技能?

&#x1f380;【开场 猫猫狐狐的对话】&#x1f43e;猫猫扒着屏幕&#xff1a;“喵&#xff1f;咱写的这句 Prompt 怎么又跑偏啦&#xff1f;明明只是想让它帮忙写一段 Python 代码&#xff0c;它偏要给咱写论文摘要……” &#x1f98a;狐狐眯着眼&#xff0c;声音带点冷意&a…

供应链管理系统入门知识:是什么,功能模块,怎么定制开发?

如果你是刚接触企业运营的新手&#xff0c;听到 “供应链管理系统” 可能会觉得有点复杂。其实&#xff0c;它就像一个 “智能管家”&#xff0c;帮企业把从买材料到卖产品的一系列流程管得明明白白。今天就用大白话给你讲清楚这个系统到底是什么&#xff0c;以及它能帮上什么忙…