class069 从递归入手三维动态规划【算法】

class069 从递归入手三维动态规划

在这里插入图片描述

在这里插入图片描述

code1 474. 一和零

// 一和零(多维费用背包)
// 给你一个二进制字符串数组 strs 和两个整数 m 和 n
// 请你找出并返回 strs 的最大子集的长度
// 该子集中 最多 有 m 个 0 和 n 个 1
// 如果 x 的所有元素也是 y 的元素,集合 x 是集合 y 的 子集
// 测试链接 : https://leetcode.cn/problems/ones-and-zeroes/

dp[i][o][z]:表示str[i…]之后选取不超过o z的子集数量
=max(不选该串,选该串)
不选该串:dp[i+1][o][z]
选该串:1+dp[i+1][o-os][z-zs]

code1 递归
code2 记忆化搜索
code3 动态规划
code4 空间压缩

package class069;

// 一和零(多维费用背包)
// 给你一个二进制字符串数组 strs 和两个整数 m 和 n
// 请你找出并返回 strs 的最大子集的长度
// 该子集中 最多 有 m 个 0 和 n 个 1
// 如果 x 的所有元素也是 y 的元素,集合 x 是集合 y 的 子集
// 测试链接 : https://leetcode.cn/problems/ones-and-zeroes/
public class Code01_OnesAndZeroes {

	public static int zeros, ones;

	// 统计一个字符串中0的1的数量
	// 0的数量赋值给全局变量zeros
	// 1的数量赋值给全局变量ones
	public static void zerosAndOnes(String str) {
		zeros = 0;
		ones = 0;
		for (int i = 0; i < str.length(); i++) {
			if (str.charAt(i) == '0') {
				zeros++;
			} else {
				ones++;
			}
		}
	}

	public static int findMaxForm1(String[] strs, int m, int n) {
		return f1(strs, 0, m, n);
	}

	// strs[i....]自由选择,希望零的数量不超过z、一的数量不超过o
	// 最多能选多少个字符串
	public static int f1(String[] strs, int i, int z, int o) {
		if (i == strs.length) {
			// 没有字符串了
			return 0;
		}
		// 不使用当前的strs[i]字符串
		int p1 = f1(strs, i + 1, z, o);
		// 使用当前的strs[i]字符串
		int p2 = 0;
		zerosAndOnes(strs[i]);
		if (zeros <= z && ones <= o) {
			p2 = 1 + f1(strs, i + 1, z - zeros, o - ones);
		}
		return Math.max(p1, p2);
	}

	// 记忆化搜索
	public static int findMaxForm2(String[] strs, int m, int n) {
		int[][][] dp = new int[strs.length][m + 1][n + 1];
		for (int i = 0; i < strs.length; i++) {
			for (int z = 0; z <= m; z++) {
				for (int o = 0; o <= n; o++) {
					dp[i][z][o] = -1;
				}
			}
		}
		return f2(strs, 0, m, n, dp);
	}

	public static int f2(String[] strs, int i, int z, int o, int[][][] dp) {
		if (i == strs.length) {
			return 0;
		}
		if (dp[i][z][o] != -1) {
			return dp[i][z][o];
		}
		int p1 = f2(strs, i + 1, z, o, dp);
		int p2 = 0;
		zerosAndOnes(strs[i]);
		if (zeros <= z && ones <= o) {
			p2 = 1 + f2(strs, i + 1, z - zeros, o - ones, dp);
		}
		int ans = Math.max(p1, p2);
		dp[i][z][o] = ans;
		return ans;
	}

	public static int findMaxForm3(String[] strs, int m, int n) {
		int len = strs.length;
		int[][][] dp = new int[len + 1][m + 1][n + 1];
		for (int i = len - 1; i >= 0; i--) {
			zerosAndOnes(strs[i]);
			for (int z = 0, p1, p2; z <= m; z++) {
				for (int o = 0; o <= n; o++) {
					p1 = dp[i + 1][z][o];
					p2 = 0;
					if (zeros <= z && ones <= o) {
						p2 = 1 + dp[i + 1][z - zeros][o - ones];
					}
					dp[i][z][o] = Math.max(p1, p2);
				}
			}
		}
		return dp[0][m][n];
	}

	public static int findMaxForm4(String[] strs, int m, int n) {
		// 代表i == len
		int[][] dp = new int[m + 1][n + 1];
		for (String s : strs) {
			// 每个字符串逐渐遍历即可
			// 更新每一层的表
			// 和之前的遍历没有区别
			zerosAndOnes(s);
			for (int z = m; z >= zeros; z--) {
				for (int o = n; o >= ones; o--) {
					dp[z][o] = Math.max(dp[z][o], 1 + dp[z - zeros][o - ones]);
				}
			}
		}
		return dp[m][n];
	}

}

code2 879. 盈利计划

// 盈利计划(多维费用背包)
// 集团里有 n 名员工,他们可以完成各种各样的工作创造利润
// 第 i 种工作会产生 profit[i] 的利润,它要求 group[i] 名成员共同参与
// 如果成员参与了其中一项工作,就不能参与另一项工作
// 工作的任何至少产生 minProfit 利润的子集称为 盈利计划
// 并且工作的成员总数最多为 n
// 有多少种计划可以选择?因为答案很大,所以 返回结果模 10^9 + 7 的值。
// 测试链接 : https://leetcode.cn/problems/profitable-schemes/

dp[i][r][s]:表示工作[i…]之后人数剩余r,利润剩余s的方案数

code1 递归
code2 记忆化搜索
code3 动态规划+空间压缩

package class069;

// 盈利计划(多维费用背包)
// 集团里有 n 名员工,他们可以完成各种各样的工作创造利润
// 第 i 种工作会产生 profit[i] 的利润,它要求 group[i] 名成员共同参与
// 如果成员参与了其中一项工作,就不能参与另一项工作
// 工作的任何至少产生 minProfit 利润的子集称为 盈利计划
// 并且工作的成员总数最多为 n
// 有多少种计划可以选择?因为答案很大,所以 返回结果模 10^9 + 7 的值。
// 测试链接 : https://leetcode.cn/problems/profitable-schemes/
public class Code02_ProfitableSchemes {

	// n : 员工的额度,不能超
	// p : 利润的额度,不能少
	// group[i] : i号项目需要几个人
	// profit[i] : i号项目产生的利润
	// 返回能做到员工不能超过n,利润不能少于p的计划有多少个
	public static int profitableSchemes1(int n, int minProfit, int[] group, int[] profit) {
		return f1(group, profit, 0, n, minProfit);
	}

	// i : 来到i号工作
	// r : 员工额度还有r人,如果r<=0说明已经没法再选择工作了
	// s : 利润还有s才能达标,如果s<=0说明之前的选择已经让利润达标了
	// 返回 : i.... r、s,有多少种方案
	public static int f1(int[] g, int[] p, int i, int r, int s) {
		if (r <= 0) {
			// 人已经耗尽了,之前可能选了一些工作
			return s <= 0 ? 1 : 0;
		}
		// r > 0
		if (i == g.length) {
			// 工作耗尽了,之前可能选了一些工作
			return s <= 0 ? 1 : 0;
		}
		// 不要当前工作
		int p1 = f1(g, p, i + 1, r, s);
		// 要做当前工作
		int p2 = 0;
		if (g[i] <= r) {
			p2 = f1(g, p, i + 1, r - g[i], s - p[i]);
		}
		return p1 + p2;
	}

	public static int mod = 1000000007;

	public static int profitableSchemes2(int n, int minProfit, int[] group, int[] profit) {
		int m = group.length;
		int[][][] dp = new int[m][n + 1][minProfit + 1];
		for (int a = 0; a < m; a++) {
			for (int b = 0; b <= n; b++) {
				for (int c = 0; c <= minProfit; c++) {
					dp[a][b][c] = -1;
				}
			}
		}
		return f2(group, profit, 0, n, minProfit, dp);
	}

	public static int f2(int[] g, int[] p, int i, int r, int s, int[][][] dp) {
		if (r <= 0) {
			return s == 0 ? 1 : 0;
		}
		if (i == g.length) {
			return s == 0 ? 1 : 0;
		}
		if (dp[i][r][s] != -1) {
			return dp[i][r][s];
		}
		int p1 = f2(g, p, i + 1, r, s, dp);
		int p2 = 0;
		if (g[i] <= r) {
			p2 = f2(g, p, i + 1, r - g[i], Math.max(0, s - p[i]), dp);
		}
		int ans = (p1 + p2) % mod;
		dp[i][r][s] = ans;
		return ans;
	}

	public static int profitableSchemes3(int n, int minProfit, int[] group, int[] profit) {
		// i = 没有工作的时候,i == g.length
		int[][] dp = new int[n + 1][minProfit + 1];
		for (int r = 0; r <= n; r++) {
			dp[r][0] = 1;
		}
		int m = group.length;
		for (int i = m - 1; i >= 0; i--) {
			for (int r = n; r >= 0; r--) {
				for (int s = minProfit; s >= 0; s--) {
					int p1 = dp[r][s];
					int p2 = group[i] <= r ? dp[r - group[i]][Math.max(0, s - profit[i])] : 0;
					dp[r][s] = (p1 + p2) % mod;
				}
			}
		}
		return dp[n][minProfit];
	}

}

code3 688. 骑士在棋盘上的概率

// 骑士在棋盘上的概率
// n * n的国际象棋棋盘上,一个骑士从单元格(row, col)开始,并尝试进行 k 次移动
// 行和列从0开始,所以左上单元格是 (0,0),右下单元格是 (n-1, n-1)
// 象棋骑士有8种可能的走法。每次移动在基本方向上是两个单元格,然后在正交方向上是一个单元格
// 每次骑士要移动时,它都会随机从8种可能的移动中选择一种,然后移动到那里
// 骑士继续移动,直到它走了 k 步或离开了棋盘
// 返回 骑士在棋盘停止移动后仍留在棋盘上的概率
// 测试链接 : https://leetcode.cn/problems/knight-probability-in-chessboard/

code 记忆化搜索

package class069;

// 骑士在棋盘上的概率
// n * n的国际象棋棋盘上,一个骑士从单元格(row, col)开始,并尝试进行 k 次移动
// 行和列从0开始,所以左上单元格是 (0,0),右下单元格是 (n-1, n-1)
// 象棋骑士有8种可能的走法。每次移动在基本方向上是两个单元格,然后在正交方向上是一个单元格
// 每次骑士要移动时,它都会随机从8种可能的移动中选择一种,然后移动到那里
// 骑士继续移动,直到它走了 k 步或离开了棋盘
// 返回 骑士在棋盘停止移动后仍留在棋盘上的概率 
// 测试链接 : https://leetcode.cn/problems/knight-probability-in-chessboard/
public class Code03_KnightProbabilityInChessboard {

	public static double knightProbability(int n, int k, int row, int col) {
		double[][][] dp = new double[n][n][k + 1];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				for (int t = 0; t <= k; t++) {
					dp[i][j][t] = -1;
				}
			}
		}
		return f(n, row, col, k, dp);
	}

	// 从(i,j)出发还有k步要走,返回最后在棋盘上的概率
	public static double f(int n, int i, int j, int k, double[][][] dp) {
		if (i < 0 || i >= n || j < 0 || j >= n) {
			return 0;
		}
		if (dp[i][j][k] != -1) {
			return dp[i][j][k];
		}
		double ans = 0;
		if (k == 0) {
			ans = 1;
		} else {
			ans += (f(n, i - 2, j + 1, k - 1, dp) / 8);
			ans += (f(n, i - 1, j + 2, k - 1, dp) / 8);
			ans += (f(n, i + 1, j + 2, k - 1, dp) / 8);
			ans += (f(n, i + 2, j + 1, k - 1, dp) / 8);
			ans += (f(n, i + 2, j - 1, k - 1, dp) / 8);
			ans += (f(n, i + 1, j - 2, k - 1, dp) / 8);
			ans += (f(n, i - 1, j - 2, k - 1, dp) / 8);
			ans += (f(n, i - 2, j - 1, k - 1, dp) / 8);
		}
		dp[i][j][k] = ans;
		return ans;
	}

}

code4 2435. 矩阵中和能被 K 整除的路径

// 矩阵中和能被 K 整除的路径
// 给一个下标从0开始的 n * m 整数矩阵 grid 和一个整数 k
// 从起点(0,0)出发,每步只能往下或者往右,你想要到达终点(m-1, n-1)
// 请你返回路径和能被 k 整除的路径数目
// 由于答案可能很大,返回答案对10^9+7取余的结果
// 测试链接 : https://leetcode.cn/problems/paths-in-matrix-whose-sum-is-divisible-by-k/

code1 递归
code2 记忆化搜索
code3 动态规划

package class069;

// 矩阵中和能被 K 整除的路径
// 给一个下标从0开始的 n * m 整数矩阵 grid 和一个整数 k
// 从起点(0,0)出发,每步只能往下或者往右,你想要到达终点(m-1, n-1)
// 请你返回路径和能被 k 整除的路径数目
// 由于答案可能很大,返回答案对10^9+7取余的结果
// 测试链接 : https://leetcode.cn/problems/paths-in-matrix-whose-sum-is-divisible-by-k/
public class Code04_PathsDivisibleByK {

	public static int mod = 1000000007;

	public static int numberOfPaths1(int[][] grid, int k) {
		int n = grid.length;
		int m = grid[0].length;
		return f1(grid, n, m, k, 0, 0, 0);
	}

	// 当前来到(i,j)位置,最终一定要走到右下角(n-1,m-1)
	// 从(i,j)出发,最终一定要走到右下角(n-1,m-1),有多少条路径,累加和%k的余数是r
	public static int f1(int[][] grid, int n, int m, int k, int i, int j, int r) {
		if (i == n - 1 && j == m - 1) {
			return grid[i][j] % k == r ? 1 : 0;
		}
		// 后续需要凑出来的余数need
 		int need = (k + r - (grid[i][j] % k)) % k;
		int ans = 0;
		if (i + 1 < n) {
			ans = f1(grid, n, m, k, i + 1, j, need);
		}
		if (j + 1 < m) {
			ans = (ans + f1(grid, n, m, k, i, j + 1, need)) % mod;
		}
		return ans;
	}

	public static int numberOfPaths2(int[][] grid, int k) {
		int n = grid.length;
		int m = grid[0].length;
		int[][][] dp = new int[n][m][k];
		for (int a = 0; a < n; a++) {
			for (int b = 0; b < m; b++) {
				for (int c = 0; c < k; c++) {
					dp[a][b][c] = -1;
				}
			}
		}
		return f2(grid, n, m, k, 0, 0, 0, dp);
	}

	public static int f2(int[][] grid, int n, int m, int k, int i, int j, int r, int[][][] dp) {
		if (i == n - 1 && j == m - 1) {
			return grid[i][j] % k == r ? 1 : 0;
		}
		if (dp[i][j][r] != -1) {
			return dp[i][j][r];
		}
		int need = (k + r - grid[i][j] % k) % k;
		int ans = 0;
		if (i + 1 < n) {
			ans = f2(grid, n, m, k, i + 1, j, need, dp);
		}
		if (j + 1 < m) {
			ans = (ans + f2(grid, n, m, k, i, j + 1, need, dp)) % mod;
		}
		dp[i][j][r] = ans;
		return ans;
	}

	public static int numberOfPaths3(int[][] grid, int k) {
		int n = grid.length;
		int m = grid[0].length;
		int[][][] dp = new int[n][m][k];
		dp[n - 1][m - 1][grid[n - 1][m - 1] % k] = 1;
		for (int i = n - 2; i >= 0; i--) {
			for (int r = 0; r < k; r++) {
				dp[i][m - 1][r] = dp[i + 1][m - 1][(k + r - grid[i][m - 1] % k) % k];
			}
		}
		for (int j = m - 2; j >= 0; j--) {
			for (int r = 0; r < k; r++) {
				dp[n - 1][j][r] = dp[n - 1][j + 1][(k + r - grid[n - 1][j] % k) % k];
			}
		}
		for (int i = n - 2, need; i >= 0; i--) {
			for (int j = m - 2; j >= 0; j--) {
				for (int r = 0; r < k; r++) {
					need = (k + r - grid[i][j] % k) % k;
					dp[i][j][r] = dp[i + 1][j][need];
					dp[i][j][r] = (dp[i][j][r] + dp[i][j + 1][need]) % mod;
				}
			}
		}
		return dp[0][0][0];
	}

}

code5 87. 扰乱字符串

// 扰乱字符串
// 使用下面描述的算法可以扰乱字符串 s 得到字符串 t :
// 步骤1 : 如果字符串的长度为 1 ,算法停止
// 步骤2 : 如果字符串的长度 > 1 ,执行下述步骤:
// 在一个随机下标处将字符串分割成两个非空的子字符串
// 已知字符串s,则可以将其分成两个子字符串x和y且满足s=x+y
// 可以决定是要 交换两个子字符串 还是要 保持这两个子字符串的顺序不变
// 即s可能是 s = x + y 或者 s = y + x
// 在x和y这两个子字符串上继续从步骤1开始递归执行此算法
// 给你两个 长度相等 的字符串 s1 和 s2,判断 s2 是否是 s1 的扰乱字符串
// 如果是,返回true ;否则,返回false
// 测试链接 : https://leetcode.cn/problems/scramble-string/

code1 递归
code2 递归优化
code3 记忆化搜索
code4 动态规划

package class069;

// 扰乱字符串
// 使用下面描述的算法可以扰乱字符串 s 得到字符串 t :
// 步骤1 : 如果字符串的长度为 1 ,算法停止
// 步骤2 : 如果字符串的长度 > 1 ,执行下述步骤:
//        在一个随机下标处将字符串分割成两个非空的子字符串
//        已知字符串s,则可以将其分成两个子字符串x和y且满足s=x+y
//        可以决定是要 交换两个子字符串 还是要 保持这两个子字符串的顺序不变
//        即s可能是 s = x + y 或者 s = y + x
//        在x和y这两个子字符串上继续从步骤1开始递归执行此算法
// 给你两个 长度相等 的字符串 s1 和 s2,判断 s2 是否是 s1 的扰乱字符串
// 如果是,返回true ;否则,返回false
// 测试链接 : https://leetcode.cn/problems/scramble-string/
public class Code05_ScrambleString {

	public static boolean isScramble1(String str1, String str2) {
		char[] s1 = str1.toCharArray();
		char[] s2 = str2.toCharArray();
		int n = s1.length;
		return f1(s1, 0, n - 1, s2, 0, n - 1);
	}

	// s1[l1....r1]
	// s2[l2....r2]
	// 保证l1....r1与l2....r2
	// 是不是扰乱串的关系
	public static boolean f1(char[] s1, int l1, int r1, char[] s2, int l2, int r2) {
		if (l1 == r1) {
			// s1[l1..r1]
			// s2[l2..r2]
			return s1[l1] == s2[l2];
		}
		// s1[l1..i][i+1....r1]
		// s2[l2..j][j+1....r2]
		// 不交错去讨论扰乱关系
		for (int i = l1, j = l2; i < r1; i++, j++) {
			if (f1(s1, l1, i, s2, l2, j) && f1(s1, i + 1, r1, s2, j + 1, r2)) {
				return true;
			}
		}
		// 交错去讨论扰乱关系
		// s1[l1..........i][i+1...r1]
		// s2[l2...j-1][j..........r2]
		for (int i = l1, j = r2; i < r1; i++, j--) {
			if (f1(s1, l1, i, s2, j, r2) && f1(s1, i + 1, r1, s2, l2, j - 1)) {
				return true;
			}
		}
		return false;
	}

	// 依然暴力尝试,只不过四个可变参数,变成了三个
	public static boolean isScramble2(String str1, String str2) {
		char[] s1 = str1.toCharArray();
		char[] s2 = str2.toCharArray();
		int n = s1.length;
		return f2(s1, s2, 0, 0, n);
	}

	public static boolean f2(char[] s1, char[] s2, int l1, int l2, int len) {
		if (len == 1) {
			return s1[l1] == s2[l2];
		}
		// s1[l1.......]  len
		// s2[l2.......]  len
		// 左 : k个   右: len - k 个
		for (int k = 1; k < len; k++) {
			if (f2(s1, s2, l1, l2, k) && f2(s1, s2, l1 + k, l2 + k, len - k)) {
				return true;
			}
		}
		// 交错!
		for (int i = l1 + 1, j = l2 + len - 1, k = 1; k < len; i++, j--, k++) {
			if (f2(s1, s2, l1, j, k) && f2(s1, s2, i, l2, len - k)) {
				return true;
			}
		}
		return false;
	}

	public static boolean isScramble3(String str1, String str2) {
		char[] s1 = str1.toCharArray();
		char[] s2 = str2.toCharArray();
		int n = s1.length;
		// dp[l1][l2][len] : int 0 -> 没展开过
		// dp[l1][l2][len] : int -1 -> 展开过,返回的结果是false
		// dp[l1][l2][len] : int 1 -> 展开过,返回的结果是true
		int[][][] dp = new int[n][n][n + 1];
		return f3(s1, s2, 0, 0, n, dp);
	}

	public static boolean f3(char[] s1, char[] s2, int l1, int l2, int len, int[][][] dp) {
		if (len == 1) {
			return s1[l1] == s2[l2];
		}
		if (dp[l1][l2][len] != 0) {
			return dp[l1][l2][len] == 1;
		}
		boolean ans = false;
		for (int k = 1; k < len; k++) {
			if (f3(s1, s2, l1, l2, k, dp) && f3(s1, s2, l1 + k, l2 + k, len - k, dp)) {
				ans = true;
				break;
			}
		}
		if (!ans) {
			for (int i = l1 + 1, j = l2 + len - 1, k = 1; k < len; i++, j--, k++) {
				if (f3(s1, s2, l1, j, k, dp) && f3(s1, s2, i, l2, len - k, dp)) {
					ans = true;
					break;
				}
			}
		}
		dp[l1][l2][len] = ans ? 1 : -1;
		return ans;
	}

	public static boolean isScramble4(String str1, String str2) {
		char[] s1 = str1.toCharArray();
		char[] s2 = str2.toCharArray();
		int n = s1.length;
		boolean[][][] dp = new boolean[n][n][n + 1];
		// 填写len=1层,所有的格子
		for (int l1 = 0; l1 < n; l1++) {
			for (int l2 = 0; l2 < n; l2++) {
				dp[l1][l2][1] = s1[l1] == s2[l2];
			}
		}
		for (int len = 2; len <= n; len++) {
			// 注意如下的边界条件 : l1 <= n - len l2 <= n - len
			for (int l1 = 0; l1 <= n - len; l1++) {
				for (int l2 = 0; l2 <= n - len; l2++) {
					for (int k = 1; k < len; k++) {
						if (dp[l1][l2][k] && dp[l1 + k][l2 + k][len - k]) {
							dp[l1][l2][len] = true;
							break;
						}
					}
					if (!dp[l1][l2][len]) {
						for (int i = l1 + 1, j = l2 + len - 1, k = 1; k < len; i++, j--, k++) {
							if (dp[l1][j][k] && dp[i][l2][len - k]) {
								dp[l1][l2][len] = true;
								break;
							}
						}
					}
				}
			}
		}
		return dp[0][0][n];
	}

}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SVN修改已提交版本的日志方法

1.在工做中一直是使用svn进行項目的版本控制的&#xff0c;有时候因为提交匆忙&#xff0c;或是忘了添加Log&#xff0c;或是Log内容有错误。遇到此类状况&#xff0c;想要在查看项目的日志时添加log或是修改log内容&#xff0c;遇到以下错误&#xff1a; Repository has not b…

2023最新最全【Wireshark 】 安装教程(附安装包)

简介 wireshark是非常流行的网络封包分析工具&#xff0c;功能十分强大。可以截取各种网络封包&#xff0c;显示网络封包的详细信息。使用wireshark的人必须了解网络协议&#xff0c;否则就看不懂wireshark了。 为了安全考虑&#xff0c;wireshark只能查看封包&#xff0c;而…

公式识别任务各个链条全部打通

目录 引言公式识别任务是什么&#xff1f;公式识别任务解决方案初探使用建议写在最后 引言 随着LaTeX-OCR模型转换问题的解决&#xff0c;公式识别任务中各个链条已经全部打通。小伙伴们可以放开膀子干了。 解决业界问题的方案&#xff0c;并不是单独训练一个模型就完事了&am…

汽车网络安全--关于UN R155认证的思考

1.UN R155概述 2020年6月25日,联合国颁布了全球首个汽车网络安全强制性法规 -- UN 155,详细规定了关于评估网络安全措施的审核条款、制造商和供应商降低网络安全风险的方法以及实施风险评估的义务等。 法规适用于与信息安全相关的M类(4轮及以上载客汽车)、N类(四轮载货汽车)…

[MySQL--进阶篇]存储引擎的体系结构、简介、特点、选择

前言 ⭐Hello!这里是欧_aita的博客。 ⭐今日语录&#xff1a;不要在乎别人怎么看你&#xff0c;因为他们根本就没有时间&#xff0c;他们只关心他们自己。 ⭐个人主页&#xff1a;欧_aita ψ(._. )>⭐个人专栏&#xff1a; 数据结构与算法 MySQL数据库 存储引擎 前言MySQL体…

Leetcode刷题笔记题解(C++):25. K 个一组翻转链表

思路&#xff1a;利用栈的特性&#xff0c;K个节点压入栈中依次弹出组成新的链表&#xff0c;不够K个节点则保持不变 /*** struct ListNode {* int val;* struct ListNode *next;* ListNode(int x) : val(x), next(nullptr) {}* };*/ #include <stack> class Solution { …

【数据结构 — 排序 — 选择排序】

数据结构 — 排序 — 选择排序 一.选择排序1.基本思想2.直接选择排序2.1算法讲解2.2.代码实现2.2.1.函数定义2.2.2.算法接口实现2.2.3.测试代码实现2.2.4.测试展示 3.堆排序3.1.算法讲解3.2.代码实现3.2.1.函数定义3.2.2.算法接口实现3.2.3.测试代码实现3.2.4.测试展示 一.选择…

【数据结构实践课设】新生报道注册管理信息系统

目录 1.主要框架 2.写入文件 3.读取文件 4.注册学生信息 5.增加学生信息 6.删除学生信息 7.按姓名查询 8.按班级查询 9.按专业查询 10.打印学生信息 11.完整代码 &#x1f308;嗨&#xff01;我是Filotimo__&#x1f308;。很高兴与大家相识&#xff0c;希望我的博客能对你有所…

【深度学习】强化学习(四)强化学习的值函数

文章目录 一、强化学习问题1、交互的对象2、强化学习的基本要素3、策略&#xff08;Policy&#xff09;4、马尔可夫决策过程5、强化学习的目标函数6、值函数1. 状态值函数&#xff08;State Value Function&#xff09;a. 状态值函数的定义b. 贝尔曼方程&#xff08;Bellman Eq…

Android 11 适配——整理总结篇

背景 > 经过检测&#xff0c;我们识别到您的应用&#xff0c;目前未适配安卓11&#xff08;API30&#xff09;&#xff0c;请您关注适配截止时间&#xff0c;尽快开展适配工作&#xff0c;避免影响应用正常发布和经营。 > targetSdkVersion30 升级适配工作参考文档&am…

107.管道(有名、无名管道)

目录 管道 无名管道 无名管道的创建 无名管道的基本用法 有名管道 写管道的进程&#xff1a; 读管道的进程&#xff1a; 管道 管道是一种进程间通信的机制&#xff0c;允许一个进程的输出直接作为另一个进程的输入。在Linux 系统中&#xff0c;管道通过 pipe 系统调用来…

javaSwing酒店管理系统

一、 使用方法&#xff1a; 在使用前&#xff0c;需要到druid.properties 配置文件中&#xff0c;修改自己对应于自己数据库的属性&#xff1b;如用户名&#xff0c;密码等 driverClassNamecom.mysql.cj.jdbc.Driver urljdbc:mysql:///hotel?useUnicodetrue&characterEn…

【C++ 程序设计入门基础】- 第3节-循环结构02

目录 while 语句 案例 while 循环 输入一个整数 n &#xff0c;输出 1~n 的所有整数。 查看运行结果&#xff1a; while 语句结构解析 do while 语句 案例 do while 循环 输入一个整数n&#xff0c;输出1&#xff5e;n的所有整数。 查看运行结果 while、do while的区别 …

Go压测工具

前言 在做Go的性能分析调研的时候也使用到了一些压测方面的工具&#xff0c;go本身也给我们提供了BenchMark性能测试用例&#xff0c;可以很好的去测试我们的单个程序性能&#xff0c;比如测试某个函数&#xff0c;另外还有第三方包go-wrk也可以帮助我们做http接口的性能压测&…

TCP为什么可靠之“重传机制”

TCP重传机制 TCP针对数据包丢失的情况&#xff0c;会通过重传机制解决&#xff0c;包括像超时重传、快速重传、选择确认SACK、D-SACK 超时重传 TCP会设置一个定时器&#xff0c;如果在发送数据之后的规定时间内&#xff0c;没有收到对方的ACK报文&#xff0c;就会触发重新发…

【Qt开发流程】之容器类2:使用STL风格迭代器进行遍历

概述 对于每个容器类&#xff0c;都有两种stl风格的迭代器类型:一种提供只读访问&#xff0c;另一种提供读写访问。应该尽可能使用只读迭代器&#xff0c;因为它们比读写迭代器快。 STL迭代器的API以数组中的指针为模型。例如&#xff0c;操作符将迭代器推进到下一项&#xf…

vue2+datav可视化数据大屏(1)

开始 &#x1f4d3; 最近打算出一个前端可视化数据大屏的系列专栏&#xff0c;这次将很全面的教大家设计可视化大屏&#xff0c;从开始到打包结束&#xff0c;其中&#xff0c;包括如何设计框架&#xff0c;如何封装axios&#xff0c;等等&#xff0c;本次使用的数据均为mock数…

关于AllowBeanDefinitionOverriding属性设置问题

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是「奇点」&#xff0c;江湖人称 singularity。刚工作几年&#xff0c;想和大家一同进步&#x1f91d;&#x1f91d; 一位上进心十足的【Java ToB端大厂…

二叉树的OJ练习(二)

通过前序遍历数组构建二叉树 题目&#xff1a;通过前序遍历的数组&#xff08;ABD##E#H##CF##G##&#xff09;构建二叉树 TreeNode* TreeCreat(char* a,int* pi) {if(a[*pi] #){(*pi);return NULL; }TreeNode* root (TreeNode*)malloc(sizeof(TreeNode));if(root NULL){p…

【Unity动画】Avatar Mask

创建 Avatar Mask可以设置那一部分骨骼运动和不运动 然后放在状态机里面的层中来混合 【后续完善】