LeetCode_动态规划1

动态规划

  • 1.动态规划总结
    • 1.1 01背
      • 1.1.1 二维数组
      • 1.1.2 一维数组
    • 1.2 完全背包
  • 2.斐波那契数(力扣509)
  • 3.爬楼梯(力扣70)
  • 4.使用最小花费爬楼梯(力扣746)
  • 5.不同路径(力扣62)
  • 6.不同路径 II(力扣63)
  • 7.整数拆分(力扣343)
  • 8.不同的二叉搜索树(力扣96)
  • 9.分割等和子集(力扣416)
  • 10.最后一块石头的重量 II(力扣1049)
  • 11.目标和(力扣494)
  • 12.一和零(力扣474)
  • 13.零钱兑换 II(力扣518)
  • 14.组合总和 Ⅳ(力扣377)
  • 15.爬楼梯(力扣70)
  • 16.零钱兑换(力扣322)
  • 17.完全平方数(力扣279)
  • 18.单词拆分(力扣139)
  • 19.打家劫舍(力扣198)
  • 20.打家劫舍 II(力扣213)
  • 21.打家劫舍 III(力扣337)

1.动态规划总结

1.1 01背

题目描述:假设背包容量为4,物品重量分别为1,3,4,价值分别为10,15,20,使装入包中的物品的价值最大。

1.1.1 二维数组

先物品后背包,每次新增一个物品,判断要不要加入到背包中

		/* 先遍历物品 */for(int i = 1;i < m;i ++){/* 再遍历背包容量 */for(int j = 1;j <= n;j ++){/* 容量>=当前物品重量,可以考虑放或不放当前物品 */if(j >= nums[i]){dp[i][j] = Math.max(dp[i - 1][j],dp[i - 1][j - nums[i]] + nums[i]);/* 否则只能选择不放当前物品 */    }else{dp[i][j] = dp[i - 1][j];}}}

先背包后物品

		for(int j = 1;j < n;j ++){for(int i = 1;i <= m;i ++){//判断当前物品到底加不加入背包if(j >= nums[i]){dp[i][j] = Math.max(dp[i - 1][j],dp[i - 1][j - nums[i]] + nums[i]);}else{dp[i][j] = dp[i - 1][j];}}}

在这里插入图片描述
两种遍历方式得到的结果相同,不过一个是逐行填写,一个是逐列填写。

1.1.2 一维数组

		for(int i = 1;i < m;i ++){for(int j = n;j >= nums[i];j --){dp[j] = Math.max(dp[j],dp[j - nums[i]] + nums[i]);}}

一维数组,即滚动数组,先物品后背包,且背包从大到小

如果背包没有从大到小

		for(int i = 1;i < m;i ++){//背包从小到大for(int j = 1;j <= n;j ++){if(j >= nums[i]){dp[j] = Math.max(dp[j],dp[j - nums[i]] + nums[i]);}}}

dp[1]=10,dp[2]=20,此时出现添加入重复物品的情况

如果不是先物品后背包

		for(int j = n;j >= 0;j --){for(int i = 1;i < m;i ++){if(j >= nums[i]){dp[j] = Math.max(dp[j],dp[j - nums[i]] + nums[i]);}}}

每次只放入一个物品

对于二维数组,时刻想着可到达当前状态的路径(从左上,正上方,正左方)
在这里插入图片描述

1.2 完全背包

在求装满背包有几种方案的时候,认清遍历顺序是非常关键的。
如果求组合数就是外层for循环遍历物品,内层for遍历背包。
如果求排列数就是外层for遍历背包,内层for循环遍历物品。

2.斐波那契数(力扣509)

class Solution {public int fib(int n) {if (n < 2){return n;}int f0 = 0, f1 = 1;int res = 0;for (int i = 2; i <= n; i++) {res = f0 + f1;f0 = f1;f1 = res;}return res;}
}
class Solution {/* 递归,不过很费时间 */public int fib(int n) {if(n < 2) return n;return fib(n - 1) + fib(n - 2);}
}

3.爬楼梯(力扣70)

//1.动态规划public int climbStairs(int n) {if(n <= 1) return n;//dp[i]:到达第i阶有多少种走法int[] dp = new int[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];}//当然此题也可以像斐波那契数列一样将数组替换为变量

4.使用最小花费爬楼梯(力扣746)

class Solution {public int minCostClimbingStairs(int[] cost) {if(cost == null){return 0;}int len = cost.length;/* dp[i]表示到达第i阶的最小花费。特别注意本题有个坑,"楼梯顶部"也算一级,所以动规数组长度为len+1 */int[] dp = new int[len + 1];/* 第一步不花费体力 */dp[0] = 0;dp[1] = 0;for (int i = 2; i <= len; i ++){dp[i] = Math.min(dp[i - 1] + cost[i - 1],dp[i - 2] + cost[i - 2]);}return dp[len];}
}

5.不同路径(力扣62)

//1.动态规划public int uniquePaths(int m, int n) {//dp[i][j]表示到第i行,第j列的不同路径总数int[][] dp = new int[m][n];for(int i = 0;i < m;i ++){dp[i][0] = 1;}for(int i = 0;i < n;i ++){dp[0][i] = 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];dp[i][j] = dp[i - 1][j] + dp[i][j - 1];}}return dp[m - 1][n - 1];}
/* 可以转化为组合问题:即从m+n-2个数中取m-1个数,有多少种方法 */public int uniquePaths3(int m, int n) {long ans = 1;for(int i = n,j = 1;j < m;i ++,j ++){ans = ans * i / j;}return (int)ans;}

6.不同路径 II(力扣63)

class Solution {/* 动态规划 */public int uniquePathsWithObstacles(int[][] obstacleGrid) {int m = obstacleGrid.length;int n = obstacleGrid[0].length;/* dp[i][j]:表示到达obstacleGrid[i][j]的可走路径数量 */int[][] dp = new int[m][n];/* 初始化第一列的值:如果发现1,则后面的行皆初始化为0 */for(int i = 0;i < m;i ++){if(obstacleGrid[i][0] != 1){dp[i][0] = 1;}else{break;}}/* 初始化第一行的值:如果发现1,则后面的列皆初始化为0 */for(int i = 0;i < n;i ++){if(obstacleGrid[0][i] != 1){dp[0][i] = 1;}else{break;}}for(int i = 1;i < m;i ++){for(int j = 1;j < n;j ++){/* 如果数组中对应位置为1,将可达路径数量置为0 */if(obstacleGrid[i][j] == 1){dp[i][j] = 0;/* 否则,统计从左边和上边到达的路径数量 */    }else{dp[i][j] = dp[i - 1][j] + dp[i][j - 1];}}}return dp[m - 1][n - 1];}
}

7.整数拆分(力扣343)

class Solution {//1.动态规划public int integerBreak(int n) {/* dp[i]为正整数i拆分结果的最大乘积 */int[] dp = new int[n + 1];/* 初始化 */dp[2] = 1;for(int i = 3; i <= n; i ++){for(int j = 1; j < i; j ++){/* j*(i-j)代表把i拆分为j和i-j两个数相乘 *//* j*dp[i-j]代表把i拆分成j和继续把(i-j)这个数拆分,* 取(i-j)拆分结果中的最大乘积与j相乘 */dp[i] = Math.max(dp[i], Math.max(j * (i - j),  j * dp[i - j]));}}return dp[n];}
}
//2.找规律/**       n          拆分*       1           0*       2           1+1*       3           1+2*       4           2+2*       5           3+2*       6           3+3*       7           3+4*       8           3+3+2*       9           3+3+3*       10          3+3+4*       11          3+3+3+2*       ...* *///按3拆分,当剩余数等于1时,和前面的3合并为4,剩余数为2时,直接相乘public int integerBreak2(int n) {if(n <= 3) return n - 1;int a = 1;while(n > 4){n -= 3;a *= 3;}return a * n;}

8.不同的二叉搜索树(力扣96)

class Solution {//1.动态规划/** 解题思路:* 假设n个节点存在二叉排序树的个数是G(n),1为根节点,2为根节点,...,n为根节点,* 当1为根节点时,其左子树节点个数为0,右子树节点个数为n-1,同理当2为根节点时,其左子树节* 点个数为1,右子树节点为n-2,所以可得G(n) = G(0)*G(n-1)+G(1)*G(n-2)+...+G(n-1)*G(0)* */public int numTrees(int n) {/* 从1到i分别为头节点组成的二叉搜索树的个数为dp[i] */int[] dp = new int[n + 1];dp[0] = 1;/* 分别以1为根节点,以2为根节点...依次类推,统计所有情况 */for(int i = 1;i <= n;i ++){/* 当以i为根节点时,有i-1种情况:分别对应左子树的数量为0,1...i-1 */for(int j = 0;j < i;j ++){dp[i] += dp[j] * dp[i - j - 1];}}return dp[n];}
}

开始进入动态规划经典题目:背包问题

9.分割等和子集(力扣416)

做这道题需要做一个等价转换,即:
是否可以从输入数组中挑选出一些正整数,使得这些数的和 等于 整个数组元素的和的一半。

// 1、二维数组
class Solution {/* 以可取的数字做为物品,以一半和做为容量,即转化为01背包问题:*  求背包在给定数字下的最大可装量,再和目标值作比较*/public boolean canPartition(int[] nums) {if (nums == null || nums.length == 0){return false;}/* 求总和 */int sum = 0;for(int num : nums){sum += num;}/* 总和不能均分为两份 */if (sum % 2 != 0){return false;}int target = sum / 2;int len = nums.length;/* dp[i][j]代表可装物品为nums[0]-nums[i](因此dp数组一维长度初始化为len),* 背包容量为j的情况下,背包内容量的最大价值 */int[][] dp = new int[len][target + 1];for (int j = 0; j <= target; j++) {if (j >= nums[0]){dp[0][j] = nums[0];}}for (int i = 1; i < len; i++) {for (int j = 0; j <= target; j++) {if (j >= nums[i]){dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - nums[i]] + nums[i]);} else {dp[i][j] = dp[i - 1][j];}}}/* 判断最大值是否等于目标值 */return dp[len - 1][target] == target;}
}

画图分析
在这里插入图片描述发现此时dp[len - 1][target]刚好为11,返回为true

//2.动态规划(一维数组)public boolean canPartition(int[] nums) {if(nums == null || nums.length == 0) return false;int len = nums.length;int sum = 0;for(int i : nums){sum += i;}if(sum % 2 != 0) return false;
//        dp[j]表示 背包总容量是j,最大可以凑成j的子集总和为dp[j]int[] dp = new int[sum / 2 + 1];for(int i = 0;i < len;i ++){for(int j = sum / 2;j >= nums[i];j --){dp[j] = Math.max(dp[j],dp[j - nums[i]] + nums[i]);}}return dp[sum / 2] == sum / 2;}

对于2这种一维数组解法
在这里插入图片描述
遍历j的时候要从后往前遍历,因为从后往前遍历时,dp[j]的改变不会影响dp[j-nums[i]];但是如果是从前往后遍历,dp[j - nums[i]]会影响dp[j]的值,从而出错

10.最后一块石头的重量 II(力扣1049)

此题和力扣416的思路一样

//1.动态规划(二维数组)public int lastStoneWeightII(int[] stones) {if(stones == null || stones.length == 0) return 0;int len = stones.length;int sum = 0;for(int i : stones){sum += i;}int target = sum / 2;//dp[i][j]:从stones[0]到stones[i]这些石头中选择放入容量为//j的背包中,使得背包容纳的石头的重量最大int[][] dp = new int[len][target + 1];for(int j = 0;j <= target;j ++){if(j >= stones[0]){dp[0][j] = stones[0];}}for(int i = 1;i < len;i ++){for(int j = 0;j <= target;j ++){if(j < stones[i]){dp[i][j] = dp[i - 1][j];}else{dp[i][j] = Math.max(dp[i - 1][j],dp[i - 1][j - stones[i]] + stones[i]);}}}return sum - dp[len - 1][target] - dp[len - 1][target];}
//2.动态规划(一维数组)public int lastStoneWeightII2(int[] stones) {if(stones == null || stones.length == 0) return 0;int len = stones.length;int sum = 0;for(int i : stones){sum += i;}int target = sum / 2;int[] dp = new int[target + 1];for(int i = 0;i < len;i ++){for(int j = target;j >= stones[i];j --){//容量为j的背包所能放下的最大石头重量dp[j] = Math.max(dp[j],dp[j - stones[i]] + stones[i]);}}return sum - dp[target] - dp[target];}

11.目标和(力扣494)

这次和之前遇到的背包问题不一样了,之前都是求容量为j的背包,最多能装多少。
本题则是装满背包有几种方法。其实这就是一个组合问题了。
在求装满背包有几种方法的情况下,递推公式一般为dp[j] += dp[j - nums[i]];

//1.动态规划(一维数组)public int findTargetSumWays2(int[] nums, int target) {if(nums == null || nums.length == 0) return 0;int len = nums.length;int sum = 0;for(int i : nums){sum += i;}if((sum + target) % 2 == 1) return 0;int size = (target + sum) / 2;if(size < 0) size = -size;//dp[j]:填满j(包括j)这么大容积的包,有dp[j]种方法int[] dp = new int[size + 1];dp[0] = 1;for(int i = 0;i < len;i ++){for(int j = size;j >= nums[i];j --){dp[j] += dp[j - nums[i]];}}return dp[size];}

12.一和零(力扣474)

//1.动态规划(三维数组)public int findMaxForm(String[] strs, int m, int n) {if(strs == null || strs.length == 0) return 0;int len = strs.length;//dp[i][m][n]:从strs[0]到strs[i]中选取子集,使得子集中最多有m个0和n个1//的最大子集的长度int[][][] dp = new int[len + 1][m + 1][n + 1];for(int i = 1;i <= len;i ++){int[] cur = caculateOneAndZero(strs[i - 1]);for(int j = 0;j <= m;j ++){for(int k = 0;k <= n;k ++){dp[i][j][k] = dp[i - 1][j][k];int zeros = cur[0];int ones = cur[1];if(j >= zeros && k >= ones){//判断当前元素要不要放入背包,如果不放入,保持原样,如果放入,比较原样和加上当前元素之后哪个子集更长dp[i][j][k] = Math.max(dp[i - 1][j][k],dp[i - 1][j - zeros][k - ones] + 1);}}}}return dp[len][m][n];}public int[] caculateOneAndZero(String s){int[] res = new int[2];for(char c : s.toCharArray()){res[c - '0'] ++;}return res;}
//2.动态规划(空间优化)public int findMaxForm2(String[] strs, int m, int n) {if(strs == null || strs.length == 0) return 0;int len = strs.length;//dp[m][n]:从strs[0]到strs[i]中选取子集,使得子集中最多有m个0和n个1//的最大子集的长度int[][] dp = new int[m + 1][n + 1];for(int i = 0;i < len;i ++){int[] cur = caculateOneAndZero(strs[i]);int zeros = cur[0];int ones = cur[1];//后两维都是倒序for(int j = m;j >= zeros;j --){for(int k = n;k >= ones;k --){dp[j][k] = Math.max(dp[j][k],dp[j - zeros][k - ones] + 1);}}}return dp[m][n];}public int[] caculateOneAndZero(String s){int[] res = new int[2];for(char c : s.toCharArray()){res[c - '0'] ++;}return res;}

13.零钱兑换 II(力扣518)

完全背包问题求不同组合的个数:
先遍历物品,再遍历背包;

//1.动态规划(一维数组)public int change(int amount, int[] coins) {if(coins == null || coins.length == 0) return 0;int len = coins.length;//dp[i]:从coins[0]到coins[i]中选取组合,使得总和为amount的不同组合的个数int[] dp = new int[amount + 1];//因为后续dp数组的结果都起于dp[0],所以初始化为1dp[0] = 1;for(int i = 0;i < len;i ++){for(int j = coins[i];j <= amount;j ++){//求个数要累积之前的所有情况dp[j] += dp[j - coins[i]];}}return dp[amount];}

好了,继续之前的问题,这里的内外循环能换吗?
显然不能,因为我们这里定义的子问题是,必须选择第k个硬币时,凑成金额i的方案。如果交换了,我们的子问题就变了,那就是对于金额 i, 我们选择硬币的方案。

14.组合总和 Ⅳ(力扣377)

完全背包问题求不同排列的个数:
先遍历背包,再遍历物品;

//1.动态规划(完全背包求排列总个数)一维数组public int combinationSum4(int[] nums, int target) {if(nums == null || nums.length == 0) return 0;int len = nums.length;//dp[i]:满足总合为i的所有组合的个数(题意中表示的是排列的所有情况)int[] dp = new int[target + 1];dp[0] = 1;//排列个数问题,先遍历背包,再遍历物品//每一次遍历,确定了容量,去找物品for(int j = 0;j <= target;j ++){for(int i = 0;i < len;i ++){if(j >= nums[i]){dp[j] += dp[j - nums[i]];}}}return dp[target];}

15.爬楼梯(力扣70)

//1.动态规划(一维数组)public int climbStairs(int n) {int[] nums = {1,2};//从nums[0]到nums[i]中选取组合,使得总和为n的所有排列的总数目int[] dp = new int[n + 1];dp[0] = 1;for(int j = 0;j <= n;j ++){for(int i = 0;i < nums.length;i ++){if(j >= nums[i]){dp[j] += dp[j - nums[i]];}}}return dp[n];}
//2.动态规划public int climbStairs(int n) {int[] dp = new int[n + 1];dp[0] = 1;dp[1] = 1;for(int i = 2;i <= n;i ++){dp[i] = dp[i - 1] + dp[i - 2];}return dp[n];}//当然此题也可以像斐波那契数列一样将数组替换为变量

16.零钱兑换(力扣322)

  1. dp[j] = Math.max(dp[j],dp[j - coins[i]] + 1);
    如果求最大个数,数组初始化为0;使得dp[j]能够及时更新,防止被dp[j]原来的值覆盖
    2.如果求最小个数,数组初始化为Integer.MAX_VALUE;原因也是防止被覆盖
public int coinChange(int[] coins, int amount) {if(coins == null || coins.length == 0) return -1;int len = coins.length;int[] dp = new int[amount + 1];for(int j = 0;j <= amount;j ++){dp[j] = Integer.MAX_VALUE;}dp[0] = 0;for(int i = 0;i < len;i ++){for(int j = coins[i];j <= amount;j ++){if(dp[j - coins[i]] != Integer.MAX_VALUE){dp[j] = Math.min(dp[j],dp[j - coins[i]] + 1);}}}return dp[amount] == Integer.MAX_VALUE ? -1 : dp[amount];}

17.完全平方数(力扣279)

public int numSquares(int n) {int maxIndex = (int)Math.sqrt(n) + 1;int[] weight = new int[maxIndex];for(int i = 1;i <= maxIndex;i ++){weight[i - 1] = i * i;}int[] dp = new int[n + 1];for(int i = 0;i <= n;i ++){dp[i] = Integer.MAX_VALUE;}dp[0] = 0;for(int i = 0;i < weight.length;i ++){for(int j = weight[i];j <= n;j ++){dp[j] = Math.min(dp[j],dp[j - weight[i]] + 1);}}return dp[n];}

18.单词拆分(力扣139)

//1.动态规划(一维数组)public boolean wordBreak(String s, List<String> wordDict) {//valid[j]:长度为j的字符串能否由wordDict中的字符串组成boolean[] valid = new boolean[s.length() + 1];//数组初始化为falseArrays.fill(valid,false);//valid[0]初始化为0,其他结果由valid[0]推出valid[0] = true;for(int i = 1;i <= s.length();i ++){for(int j = 0;j < i;j ++){if(wordDict.contains(s.substring(j,i)) && valid[j]){valid[i] = true;}}}return valid[s.length()];}

19.打家劫舍(力扣198)

//1.动态规划(一维数组)public int rob(int[] nums) {if(nums == null || nums.length == 0) return 0;int len = nums.length;//dp[i]:考虑下标i(包括i)以内的房屋,最多可以偷窃的金额为dp[i]。int[] dp = new int[len + 1];dp[1] = nums[0];for(int i = 2;i <= len;i ++){dp[i] = Math.max(dp[i - 1],dp[i - 2] + nums[i - 1]);}return dp[len];}

20.打家劫舍 II(力扣213)

//1.动态规划(一维数组)public int rob(int[] nums) {if(nums == null || nums.length == 0) return 0;if(nums.length == 1) return nums[0];if(nums.length == 2) return Math.max(nums[0],nums[1]);//因为首尾不能同时取,将nums分成两部分,返回两部分的最大值中的较大值return Math.max(robRange(nums,0,nums.length - 2),robRange(nums,1,nums.length - 1));}//下面也可以使用变量代替数组进行空间优化public int robRange(int[] nums,int start,int end){int len = end - start + 1;int[] dp = new int[len];dp[0] = nums[start];dp[1] = Math.max(nums[start],nums[start + 1]);for(int i = 2;i < len;i ++){dp[i] = Math.max(dp[i - 1],dp[i - 2] + nums[i + start]);}return dp[len - 1];}

21.打家劫舍 III(力扣337)

//1.递归(超出时间限制)public int rob(TreeNode root) {if(root == null){return 0;}int money = root.val;if(root.left != null){money += (rob(root.left.left) + rob(root.left.right));}if(root.right != null){money += (rob(root.right.left) + rob(root.right.right));}//两种情况,当前节点取和不取return Math.max(money,rob(root.left) + rob(root.right));}
//2.树形动态规划public int rob2(TreeNode root) {int[] ans = robAction(root);//最终取 当前节点取和不取的最大值return Math.max(ans[0],ans[1]);}public int[] robAction(TreeNode root){//res[0]:当前节点不取时获得的最大金额//res[1]:当前节点取时获得的最大金额int[] res = new int[2];if(root == null) return res;int[] left = robAction(root.left);int[] right = robAction(root.right);//当前节点不取,最大值 = (左孩子取和不取的最大值) + (右孩子取和不取的最大值)res[0] = Math.max(left[0],left[1]) + Math.max(right[0],right[1]);//当前节点取,最大值 = 左孩子不取 + 右孩子不取 + 当前节点的值res[1] = left[0] + right[0] + root.val;return res;}

买卖股票问题总结:共有六个股票相关问题
1.只能买卖一次
2.可以买卖多次
3.最多买卖两次
4.最多买卖k次
5.买卖多次,卖出有一天冷冻期
6.买卖多次,每次有手续费

做股票问题时一定要注意定义的是第i天处于j状态,这个状态有可能是之前延续过来的,也有可能是今天才变为这个状态,理解这一点很重要

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

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

相关文章

【STM32】HAL库中的实现(九):SPI(串行外设接口)

SPI 接口通信原理 SPI&#xff08;Serial Peripheral Interface&#xff09;是全双工主从通信协议&#xff0c;特点是&#xff1a; 信号线功能SCK串行时钟MOSI主设备输出&#xff0c;从设备输入MISO主设备输入&#xff0c;从设备输出CS&#xff08;NSS&#xff09;片选信号&am…

Git常用操作大全(附git操作命令)

Git常用操作大全 一、基础配置 1.1 设置用户名和邮箱 git config --global user.name "你的名字" git config --global user.email "你的邮箱"1.2 查看配置 git config --list二、仓库管理 2.1 初始化本地仓库 git init2.2 克隆远程仓库 git clone <仓库…

详解flink table api基础(三)

文章目录1.使用flink的原因&#xff1a;2. Flink支持两种模式&#xff1a;3. flink table api工作原理&#xff1a;4. Flink table api 使用5. select语句&flink table api&#xff1a;6. 使用flink table api 创建table7. 使用flink table api 写流式数据输出到表或sink8.…

Vue2+Vue3前端开发_Day5

参考课程: 【黑马程序员 Vue2Vue3基础入门到实战项目】 [https://www.bilibili.com/video/BV1HV4y1a7n4] ZZHow(ZZHow1024) 自定义指令 基本语法&#xff08;全局 & 局部注册&#xff09; 介绍&#xff1a;自己定义的指令&#xff0c;可以封装一些 DOM 操作&#xff0c…

机器学习--决策树2

目录 第一代裁判&#xff1a;ID3 与信息增益的 “偏爱” 第二代裁判&#xff1a;C4.5 用 “增益率” 找平衡 第三代裁判&#xff1a;CART 的 “基尼指数” 新思路 遇到连续值&#xff1f;先 “砍几刀” 再说 给决策树 “减肥”&#xff1a;剪枝的学问 动手试试&#xff1…

yggjs_react使用教程 v0.1.1

yggjs_react是一个用于快速创建React项目的工具&#xff0c;它集成了Vite、TypeScript、Zustand和React Router等现代前端技术栈&#xff0c;帮助开发者快速搭建高质量的React应用。 快速入门 快速入门部分将指导您如何安装yggjs_react工具、创建新项目并启动开发服务器。 安…

vulhub可用的docker源

这一块不太容易找&#xff0c;我试了好几个源&#xff0c;下面是20250820测试可用源 编辑方法sudo mkdir -p /etc/docker sudo vim /etc/docker/daemon.json 配置内容 [1] {"registry-mirrors" : ["https://docker.registry.cyou", "https://docker-…

基于YOLOv8-SEAttention与LLMs融合的农作物害虫智能诊断与防控决策系统

1. 引言 1.1 研究背景与意义 农作物虫害是制约农业产量与质量的重要因素。据FAO报告&#xff0c;全球每年因病虫害造成的粮食损失高达 20%–40%。传统人工巡查与经验诊断具有时效性差、成本高与专业人才不足等缺陷。近年来&#xff0c;计算机视觉特别是目标检测技术在农业检测…

从零开始构建GraphRAG红楼梦知识图谱问答项目(三)

文章结尾有CSDN官方提供的学长的联系方式&#xff01;&#xff01; 欢迎关注B站从零开始构建一个基于GraphRAG的红楼梦项目 第三集01 搭建后端服务 创建一个python文件server.py 完整源码放到文章最后了。 1.1 graphrag 相关导入 # GraphRAG 相关导入 from graphrag.query.cont…

S32K328(Arm Cortex-M7)适配CmBacktrace错误追踪

CmBacktrace 相当于重写了hard_fault函数&#xff0c;在hard_fault函数里面去分析SCB寄存器的信息和堆栈信息&#xff0c;然后把这些信息打印出来(或者写到flash)&#xff1b;通过使用串口输出产生hard_fault的堆栈信息&#xff0c;然后利用addr2line工具反推出具体的代码执行函…

AI研究引擎的简单技术实现步骤

产品愿景与核心功能 1.1 产品使命 “洞见 Weaver”是一个全栈AI Web应用,旨在将用户的复杂研究问题,通过AI驱动的动态思维导图和结构化报告,转化为一次沉浸式的、可追溯的视觉探索之旅。我们的使命是,将AI复杂的推理过程透明化,将人类的探索直觉与AI的分析能力无缝结合,…

open webui源码分析5-Tools

本文从最简单的时间工具入手&#xff0c;分析Tools相关的代码。一、安装工具git clone https://github.com/open-webui/openapi-servers cd openapi-servers# 进入时间工具目录 cd servers/timepip install -r requirements.txt# 启动服务 uvicorn main:app --host 0.0.0.0 --r…

windows下通过vscode远程调试linux c/cpp程序配置

windows下通过vscode远程调试linux c/cpp程序配置vscode插件配置linux依赖工具安装launch.json配置vscode插件配置 CodeLLDB插件需要提前下载&#xff1a; linux依赖工具安装 sudo apt update sudo apt install cmake clangdlaunch.json配置 {"version": "0…

IDEA报JDK版本问题

解决思路&#xff1a;1.找到配置jdk的IDEA配置位置settings和project structure2.先配置setting3.再修改项目结构

VirtualBox 安装 Ubuntu Server 系统及 Ubuntu 初始配置

文章目录简介VirtualBoxUbuntu Server 简介Ubuntu Server 下载安装 Ubuntu Server首选项配置导入系统镜像配置系统用户配置内存 CPU 虚拟硬盘开始安装 Ubuntu安装完成登录系统配置网络Ubuntu 系统配置安装常用工具安装 SSH设置 root 密码配置 IP 地址&#xff08;推荐自动分配I…

Milvus 可观测性最佳实践

Milvus 介绍 Milvus 是一个开源的向量数据库&#xff0c;专为处理大规模、高维度向量数据而设计&#xff0c;广泛应用于人工智能、推荐系统、图像检索、自然语言处理等场景。它支持亿级向量的高效存储与快速检索&#xff0c;内置多种相似度搜索算法&#xff08;如 HNSW、IVF、…

arcgis-空间矫正工具(将下发数据A的信息放置原始数据B的原始信息并放置到成果数据C中,主要按下发数据A的范围)

正常来说&#xff0c;可以直接相交获取&#xff0c;但是会存在原始数据B将下发数据A进行分割&#xff0c;所以相交功能会导致最终成果会产生稀碎图斑及图斑切割&#xff0c;因此&#xff0c;经学习了解&#xff0c;学会此方法进行既保留原始数据B的信息&#xff0c;又按下发数据…

MySQL深分页慢问题及性能优化

在数据驱动的应用中&#xff0c;分页是不可或缺的功能。然而&#xff0c;当数据量达到百万甚至千万级别时&#xff0c;传统基于 LIMIT OFFSET 的分页方式会遭遇严重的性能瓶颈&#xff0c;即“深分页”问题。本文将剖析其根源并提供主流的优化策略。问题根源&#xff1a;LIMIT …

漫谈《数字图像处理》之平滑

在数字图像处理中&#xff0c;平滑&#xff08;Smoothing&#xff09; 的核心目标是降低图像噪声、模糊细节或简化纹理&#xff0c;本质是通过 “局部邻域运算” 对像素值进行 “平均化” 或 “规整化”&#xff0c;让图像整体更 “平缓”。形态学平滑与高斯平滑、均值平滑等其…

机器学习之数据预处理学习总结

在机器学习中&#xff0c;数据预处理是模型训练前至关重要的环节&#xff0c;直接影响模型的性能和准确性。通过本次学习&#xff0c;我系统掌握了数据预处理的核心方法与工具&#xff0c;现将主要内容总结如下&#xff1a;一、缺失值处理缺失值是实际数据中常见的问题&#xf…