背包问题DP(01背包 完全背包 多重背包 分组背包)

news2025/4/12 19:01:40

目录

  • 背包问题的简介
    • 背包问题的定义
    • 背包问题的分类
  • 01背包问题
    • 典型例题
      • 实现思路
      • 二维数组代码实现
      • 一维数组优化实现
      • 扩展:记忆化搜索 + DPS 实现
    • 01背包之恰好装满
      • 思路
      • 代码实现
  • 完全背包问题
    • 典型例题
      • 思路分析
      • 二维数组代码实现
      • 一维数组优化实现
  • 多重背包问题
    • 多重背包问题的三种解法
    • 朴素解法
      • 典型题目
        • 思路
        • 二维数组代码实现
        • 一维数组优化实现
    • 二进制解法
      • 典型题目
        • 思路
        • 二维数组代码实现
        • 一维数组优化实现
  • 分组背包问题
    • 典型例题
      • 思路分析
      • 二维数组代码实现
      • 一维数组优化实现


背包问题的简介

背包问题的定义

一个可承载重量为 W W W 的背包和 N N N 件物品,每件物品有一个重量 w w w 和一个价值 v v v。现在让你用这个背包装物品,要求装入的物品总重量不能超过背包可承载重量 W W W,同时使装入物品的总价值最大。


背包问题的分类

背包问题分类


01背包问题

典型例题

题目描述:
V V V 件物品和一个容量是 V V V 的背包。每件物品只能使用一次。

i i i 件物品的体积是 v i v_i vi,价值是 w i w_i wi

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。

输入格式:
第一行两个整数, N , V N,V N,V,用空格隔开,分别表示物品数量和背包容积。

接下来有 N N N 行,每行两个整数 v i , w i v_i,w_i vi,wi,用空格隔开,分别表示第 i i i 件物品的体积和价值。

输出格式:
输出一个整数,表示最大价值。

数据范围:

0 < N , V ≤ 1000 0 < N,V \leq 1000 0<N,V1000
0 < v i , w i ≤ 1000 0 < v_i,w_i \leq 1000 0<vi,wi1000

输入样例:

4 5
1 2
2 4
3 4
4 5

输出样例:

8

实现思路

DP问题的思路模板
在这里插入图片描述


这里使用二维的状态表示 f [ i ] [ j ] f[i][j] f[i][j],用来表示 只从前 i i i 件物品中选, 总体积 ≤ j \leq j j

这样在状态计算中, 就可以把集合划分为 f [ i − 1 ] [ j ] f[i - 1][j] f[i1][j](即只从前 i − 1 i - 1 i1 件物品中选且不选择第 i i i 件物品), f [ i − 1 ] [ j − v [ i ] ] + w [ i ] f[i - 1][j - v[i]] + w[i] f[i1][jv[i]]+w[i] v [ i ] v[i] v[i] 表示第 i i i 件物品的体积, w [ i ] w[i] w[i] 表示第 i i i 件物品的权重)(即只从前 i − 1 i - 1 i1 件物品中选且选了第 i i i 件物品)。

通过以上思路可以得到状态转移方程:
f [ i ] [ j ] = m a x ( f [ i − 1 ] [ j ] , f [ i − 1 ] [ j − v [ i ] ] + w [ i ] ) \large f[i][j] = max(f[i - 1][j],f[i - 1][j - v[i]] + w[i]) f[i][j]=max(f[i1][j],f[i1][jv[i]]+w[i])


二维数组代码实现

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

const int N = 1010;
int v[N], w[N], f[N][N];

int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; ++i)
	{
		cin >> v[i] >> w[i];
		for (int j = 0; j <= m; ++j)
		{
			f[i][j] = f[i - 1][j];
			if (j >= v[i]) f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]);
		}
	}
	cout << f[n][m] << endl;
	return 0;
}

一维数组优化实现

f [ i ] [ j ] = m a x ( f [ i − 1 ] [ j ] , f [ i − 1 ] [ j − v [ i ] ] + w [ i ] ) \large f[i][j] = max(f[i - 1][j],f[i - 1][j - v[i]] + w[i]) f[i][j]=max(f[i1][j],f[i1][jv[i]]+w[i])
由状态转移方程,可得 f [ i ] [ j ] f[i][j] f[i][j] 都是由 [ i − 1 ] [i - 1] [i1] 更新过来的,故省略一个维度,仅保留 [ j ] [j] [j] 的背包容量的维度。

即变为 f [ j ] = m a x ( f [ j ] , f [ j − v [ i ] ] + w [ i ] ) f[j] = max(f[j],f[j - v[i]] + w[i]) f[j]=max(f[j],f[jv[i]]+w[i]) ,时间复杂度不变,但空间复杂度减少。由于要满足 i f ( j > = v [ i ] ) if (j >= v[i]) if(j>=v[i]) 条件,只需让 j j j w [ i ] w[i] w[i] 开始遍历。


由于二维数组中状态计算都是由上一行的数据更新过来,即都是从左上方更新过来的。
如图:
在这里插入图片描述

由于优化为了一维数组,可看作二维数组被压缩为了一行,这个时候若是保留二维度数组的从左向右更新模式,就会导致左边数值被提前更新。

如果用二维数组来看的话其更新模式如图:
在这里插入图片描述
从图可知这样更新会出错误

因此要改变更新模式,改为从右边往左的更新方式,这样每回更新所用到的右边数据就都是没有更新过的数据。

代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

const int N = 1010;
int v[N], w[N], f[N];

int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; ++i)
	{
		cin >> v[i] >> w[i];
		for (int j = m; j >= v[i]; --j) // 满足if (j >= v[i])条件,同时改变遍历方向
			f[j] = max(f[j], f[j - v[i]] + w[i]);
	}
	cout << f[m] << endl;
	return 0;

扩展:记忆化搜索 + DPS 实现

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

const int N = 1010;
int n, m, f[N][N], w[N], v[N];

int dfs(int u, int r)
{
	if (~f[u][r]) return f[u][r];
	if (u == n + 1) return 0;
	if (v[u] <= r) return f[u][r] = max(dfs(u + 1, r), dfs(u + 1, r - v[u]) + w[u]);
	return f[u][r] = dfs(u + 1, r);
}
int main()
{
	cin >> n >> m;
	memset(f, -1, sizeof f);
	for (int i = 1; i <= n; ++i) cin >> v[i] >> w[i];
	cout << dfs(1, m) << endl;
	return 0;
}

01背包之恰好装满

n n n 个体积和价值分别为 v i , w i v_i,w_i vi,wi 的物品,现从这些物品中挑选出总体积 恰好 m m m 的物品,求所有方案中价值总和的最大值。

输入:包含多组测试用例,每一例的开头为两位整数 n 、 m n、m nm( 1 ≤ n ≤ 10000 , 1 ≤ m ≤ 1000 1 \leq n \leq 10000,1 \leq m \leq 1000 1n10000,1m1000),接下来有 n n n 行,每一行有两位整数 v i 、 w i v_i、w_i viwi( 1 ≤ v i ≤ 10000 , 1 ≤ w i ≤ 100 1 \leq v_i \leq 10000,1 \leq w_i \leq 100 1vi10000,1wi100)。

输出:为一行,即所有方案中价值总和的最大值。若不存在刚好填满的情况,输出 −1

测试用例:

3 4
1 2
2 5
2 1

3 4
1 2
2 5
5 1

答案:

6
-1

思路

前序状态 f[i−1][j]前序状态 f[i−1][j−w[i]]当前状态 f[i][j]转移来源
有效状态(满)有效状态(满)有效状态(满) m a x ( f [ i − 1 ] [ j ] , f [ i − 1 ] [ j − w [ i ] ] + v [ i ] ) max(f[i−1][j],f[i−1][j−w[i]]+v[i]) max(f[i1][j],f[i1][jw[i]]+v[i])
无效状态(不满)有效状态(满)有效状态(满) m a x ( f [ i − 1 ] [ j − w [ i ] ] + v [ i ] , − I N F ) max(f[i−1][j−w[i]]+v[i],−INF) max(f[i1][jw[i]]+v[i],INF)
有效状态(满)无效状态(不满)有效状态(满) m a x ( f [ i − 1 ] [ j ] , − I N F ) max(f[i−1][j],−INF) max(f[i1][j],INF)
无效状态(不满)无效状态(不满)无效状态(不满) f [ i ] [ j ] = m a x ( f [ i − 1 ] [ j ] , f [ i − 1 ] [ j − w ] + v ) f[i][j]=max(f[i−1][j],f[i−1][j−w]+v) f[i][j]=max(f[i1][j],f[i1][jw]+v) − I N F −INF INF 会被加上 v v v,不再是 − I N F −INF INF,但肯定是负数。

恰好装满:

  • 求最大值时,除了 f [ 0 ] f[0] f[0] 0 0 0,其他都初始化为无穷小 -0x3f3f3f3f

  • 求最小值时,除了 f [ 0 ] f[0] f[0] 0 0 0,其他都初始化为无穷大 0x3f3f3f3f

在这里插入图片描述


代码实现

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

const int N = 1010;
int f[N][N], v[N], w[N];

int main()
{
	int n, m;
	while (cin >> n >> m)
	{
		memset(f, -0x3f, sizeof f);
		for (int i = 0; i < N; ++i) f[i][0] = 0;

		for (int i = 1; i <= n; ++i)
		{
			cin >> v[i] >> w[i];
			for (int j = m; j >= v[i]; --j)
				f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]);
		}
		if (f[n][m] < 0) cout << -1 << endl;
		else cout << f[n][m] << endl;
	}
	return 0;
}

完全背包问题

典型例题

题目描述:
N N N 种物品和一个容量是 V V V 的背包,每种物品都有无限件可用。

i i i 种物品的体积是 v i v_i vi,价值是 w i w_i wi

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。

输出最大价值。

输入格式:
第一行两个整数, N , V N,V N,V,用空格隔开,分别表示物品种数和背包容积。

接下来有 N N N 行,每行两个整数 v i , w i v_i,w_i vi,wi,用空格隔开,分别表示第 i i i 种物品的体积和价值。

输出格式:
输出一个整数,表示最大价值。

数据范围:

0 < N , V ≤ 1000 0<N,V≤1000 0<N,V1000

0 < v i , w i ≤ 1000 0<v_i,w_i≤1000 0<vi,wi1000

输入样例:

4 5
1 2
2 4
3 4
4 5

输出样例:

10

思路分析

在这里插入图片描述

与01背包问题的思路大体相同, 主要在状态的计算方面有所不同,由于完全背包问题下所有可以选用的物品数量是无限的。因此状态转移方程为: f [ i ] [ j ] = m a x ( f [ i − 1 ] [ j ] , f [ i − 1 ] [ j − v [ i ] ] + w [ i ] , . . . , f [ i − 1 ] [ j − k ∗ v [ i ] ] + k ∗ w [ i ] ) f[i][j] = max(f[i - 1][j],f[i-1][j - v[i]]+w[i],...,f[i-1][j-k * v[i]]+k*w[i]) f[i][j]=max(f[i1][j],f[i1][jv[i]]+w[i],...,f[i1][jkv[i]]+kw[i])

由于 f [ i ] [ j − v [ i ] ] = m a x ( f [ i − 1 ] [ j − v [ i ] ] , f [ i − 1 ] [ j − 2 ∗ v [ i ] ] + w [ i ] , . . . , f [ i − 1 ] [ j − k ∗ v [ i ] ] + k ∗ w [ i ] ) f[i][j-v[i]] = max(f[i - 1][j-v[i]],f[i-1][j - 2*v[i]]+w[i],...,f[i-1][j-k * v[i]]+k*w[i]) f[i][jv[i]]=max(f[i1][jv[i]],f[i1][j2v[i]]+w[i],...,f[i1][jkv[i]]+kw[i])


为什么最后一项不是 f [ i − 1 ] [ j − ( k + 1 ) ∗ v [ i ] ] + ( k + 1 ) ∗ w [ i ] f[i-1][j-(k+1) * v[i]]+(k+1)*w[i] f[i1][j(k+1)v[i]]+(k+1)w[i]

  • 这是因为 k k k 的值只与背包最大容量相关

由上面两个公式我们可以推导出:

f [ i ] [ j ] = m a x ( f [ i − 1 ] [ j ] , f [ i ] [ j − v [ i ] ] ) f[i][j] = max(f[i - 1][j], f[i][j-v[i]]) f[i][j]=max(f[i1][j],f[i][jv[i]])


二维数组代码实现

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

const int N = 1010;
int f[N][N], w[N], v[N];

int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; ++i)
	{
		cin >> v[i] >> w[i];
		for (int j = 0; j <= m; ++j)
		{
			f[i][j] = f[i - 1][j];
			if (j >= v[i]) f[i][j] = max(f[i][j], f[i][j - v[i]] + w[i]);
		}
	}
	cout << f[n][m] << endl;
	return 0;
}

一维数组优化实现

由状态转移方程:
f [ i ] [ j ] = m a x ( f [ i − 1 ] [ j ] , f [ i ] [ j − v [ i ] ] ) f[i][j] = max(f[i - 1][j], f[i][j-v[i]]) f[i][j]=max(f[i1][j],f[i][jv[i]])

类似于01背包问题的一维优化,但是由于 f [ i ] [ j − v [ i ] ] f[i][j-v[i]] f[i][jv[i]] 是从数组中同行的左边数据更新而来,因此遍历方向只能从左向右,使用左边已被更新后的数据来更新右边的数据。

达到如下图的更新效果:
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

const int N = 1010;
int f[N], w[N], v[N];

int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; ++i)
	{
		cin >> v[i] >> w[i];
		for (int j = v[i]; j <= m; ++j) f[j] = max(f[j], f[j - v[i]] + w[i]);
	}
	cout << f[m] << endl;
	return 0;
}

多重背包问题

多重背包问题的三种解法

注:

  • n 表示物品个数
  • V 表示背包的容量
① 朴素版本② 二进制优化版本③ 单调队列优化版本
n ≤ 100 , V ≤ 100 n≤100,V≤100 n100,V100 n ≤ 1000 , V ≤ 2000 n≤1000,V≤2000 n1000,V2000 n ≤ 1000 , V ≤ 20000 n≤1000,V≤20000 n1000,V20000

朴素解法

典型题目

题目描述:
N N N 种物品和一个容量是 V V V 的背包。

i i i 种物品最多有 s i s_i si 件,每件体积是 v i v_i vi,价值是 w i w_i wi

求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。
输出最大价值。

输入格式:
第一行两个整数, N , V N,V N,V,用空格隔开,分别表示物品种数和背包容积。

接下来有 N N N 行,每行三个整数 v i , w i , s i v_i,w_i,s_i vi,wi,si,用空格隔开,分别表示第 i i i 种物品的体积、价值和数量。

输出格式:
输出一个整数,表示最大价值。

数据范围:
0 < N , V ≤ 100 0<N,V≤100 0<N,V100
0 < v i , w i , s i ≤ 100 0<v_i,w_i,s_i≤100 0<vi,wi,si100

输入样例:

4 5
1 2 3
2 4 1
3 4 3
4 5 2

输出样例:

10

思路

在这里插入图片描述


二维数组代码实现

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

const int N = 110;
int f[N][N];

int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; ++i)
	{
		int v, w, s;
		cin >> v >> w >> s;
		for (int j = 0; j <= m; ++j)
			for (int k = 0; k <= s && k * v <= j; ++k) // 遍历第i个物品的所有选取情况
				f[i][j] = max(f[i][j], f[i - 1][j - k * v] + w * k);
	}
	cout << f[n][m] << endl;
	return 0;
}

一维数组优化实现

注意:一维化后从右向左遍历。

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

const int N = 110;
int f[N];

int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; ++i)
	{
		int v, w, s;
		cin >> v >> w >> s;
		for (int j = m; j >= v; --j) // 注意从右向左遍历
		{
			for (int k = 0; k <= s && k * v <= j; ++k)
				f[j] = max(f[j], f[j - k * v] + k * w);
		}
	}
	cout << f[m] << endl;
	return 0;
}

二进制解法

典型题目

题目描述:
N N N 种物品和一个容量是 V V V 的背包。

i i i 种物品最多有 s i s_i si 件,每件体积是 v i v_i vi,价值是 w i w_i wi

求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。
输出最大价值。

输入格式:
第一行两个整数, N , V N,V N,V,用空格隔开,分别表示物品种数和背包容积。

接下来有 N N N 行,每行三个整数 v i , w i , s i v_i,w_i,s_i vi,wi,si,用空格隔开,分别表示第 i i i 种物品的体积、价值和数量。

输出格式:
输出一个整数,表示最大价值。

数据范围:
0 < N ≤ 1000 0<N≤1000 0<N1000
0 < V ≤ 2000 0<V≤2000 0<V2000
0 < v i , w i , s i ≤ 2000 0<v_i,w_i,s_i≤2000 0<vi,wi,si2000

输入样例:

4 5
1 2 3
2 4 1
3 4 3
4 5 2

输出样例:

10

思路

  • 对于每种物品,将其数量进行二进制拆分。例如数量为13的物品,可以拆分为1,2,4,6这四个子集。
  • 对每种物品的每个子集,将其看作一个新的物品,权值不变,数量变为子集的数量。
  • 对这些新的物品进行01背包的动态规划。
  • 在进行动态规划时,需要按照子集的数量从小到大的顺序进行遍历,以保证每个子集只被选择一次。
  • 最后得到的解即为原问题的最优解。

二维数组代码实现

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

const int N = 12010, M = 2010; // log_2 2000 = 12,得到二进制分解之后的物品数量约为 12*1000
int f[N][M], v[N], w[N];

int main()
{
	int n, m, idx = 0;
	cin >> n >> m;
	for (int i = 1; i <= n; ++i)
	{
		int a, b, s;
		cin >> a >> b >> s;

		// 进行二进制分解
		int k = 1;
		while (k <= s)
		{
			idx++;
			v[idx] = a * k;
			w[idx] = b * k;
			s -= k;
			k *= 2;
		}
		if (s > 0)
		{
			idx++;
			v[idx] = a * s;
			w[idx] = b * s;
		}
	}
	n = idx; // 用二进制分解后的物品数量更新当前物品数量
	for (int i = 1; i <= n; ++i) // 经典01背包问题解决
	{
		for (int j = 0; j <= m; ++j)
		{
			f[i][j] = f[i - 1][j];
			if (v[i] <= j) f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]);
		}
	}
	cout << f[n][m] << endl;
	return 0;
}

一维数组优化实现

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

const int N = 12010, M = 2010;
int f[N], w[N], v[N];

int main()
{
	int n, m, idx = 0;
	cin >> n >> m;
	for (int i = 1; i <= n; ++i)
	{
		int a, b, s, k = 1;
		cin >> a >> b >> s;
		while (k <= s)
		{
			idx++;
			v[idx] = a * k;
			w[idx] = b * k;
			s -= k;
			k *= 2;
		}
		if (s > 0)
		{
			idx++;
			v[idx] = a * s;
			w[idx] = b * s;
		}
	}
	n = idx;
	for (int i = 1; i <= n; ++i)
	{
		for (int j = m; j >= v[i]; --j)
			f[j] = max(f[j], f[j - v[i]] + w[i]);
	}
	cout << f[m] << endl;
	return 0;
}

分组背包问题

典型例题

题目描述:
N N N 组物品和一个容量是 V V V 的背包。

每组物品有若干个,同一组内的物品最多只能选一个。

每件物品的体积是 v i j v_{ij} vij,价值是 w i j w_{ij} wij,其中 i i i 是组号, j j j 是组内编号。

求解将哪些物品装入背包,可使物品总体积不超过背包容量,且总价值最大。

输出最大价值。

输入格式:
第一行有两个整数 N , V N,V NV,用空格隔开,分别表示物品组数和背包容量。

接下来有 N N N 组数据:

每组数据第一行有一个整数 S i S_i Si,表示第 i i i 个物品组的物品数量;每组数据接下来有 S i S_i Si 行,每行有两个整数 v i j , w i j v_{ij},w_{ij} vij,wij,用空格隔开,分别表示第 i i i 个物品组的第 j j j 个物品的体积和价值;

输出格式:
输出一个整数,表示最大价值。

数据范围:
0 < N , V ≤ 100 0<N,V≤100 0<N,V100

0 < S i ≤ 100 0<S_i≤100 0<Si100

0 < v i j , w i j ≤ 100 0<v_{ij},w_{ij}≤100 0<vij,wij100

输入样例:

3 5
2
1 2
2 4
1
3 4
1
4 5

输出样例:

8

思路分析

在这里插入图片描述


二维数组代码实现

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

const int N = 110;
int f[N][N], v[N][N], w[N][N], s[N];

int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; ++i)
	{
		cin >> s[i];
		for (int j = 0; j < s[i]; ++j) cin >> v[i][j] >> w[i][j];
	}
	for (int i = 1; i <= n; ++i)
	{
		for (int j = 0; j <= m; ++j)
		{
			for (int k = 0; k < s[i]; ++k)
			{
				f[i][j] = f[i - 1][j];
				if (v[i][k] <= j) f[i][j] = max(f[i][j], f[i - 1][j - v[i][k]] + w[i][k]);
			}
		}
	}
	cout << f[n][m] << endl;
	return 0;
}

一维数组优化实现

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

const int N = 110;
int f[N], v[N][N], w[N][N], s[N];

int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; ++i)
	{
		cin >> s[i];
		for (int j = 0; j < s[i]; ++j) cin >> v[i][j] >> w[i][j];
	}
	for (int i = 1; i <= n; ++i)
	{
		for (int j = m; j >= 0; --j) // 由于组内的物体体积无法直接提出,所以将判断情况后置
			for (int k = 0; k < s[i]; ++k)
				// 后置的判断情况
				if (v[i][k] <= j) f[j] = max(f[j], f[j - v[i][k]] + w[i][k]);
	}
	cout << f[m] << endl;
	return 0;
}

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

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

相关文章

网易一面:单节点2000Wtps,Kafka怎么做的?

说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如网易、有赞、希音、百度、网易、滴滴的面试资格&#xff0c;遇到一几个很重要的面试题&#xff1a; 问题1&#xff1a;单节点2000Wtps&#xff0c;Kafka高性能原理是什么&#…

测试人员如何通过AI提高工作效率!

随着AI技术的兴起&#xff0c;像OpenAI推出的ChatGPT、Microsoft发布的Microsoft 365 Copilot、阿里的通义千问、百度的文心一言、华为的盘古大模型等。很多测试人员开始担心&#xff0c;岗位是否会被AI取代&#xff1f;其实取代你的不是AI&#xff0c;而是会使用AI的测试人&am…

[论文分享]VOLO: Vision Outlooker for Visual Recognition

VOLO: Vision Outlooker for Visual Recognition 概述 视觉 transformer&#xff08;ViTs&#xff09;在视觉识别领域得到了广泛的探索。由于编码精细特征的效率较低&#xff0c;当在 ImageNet 这样的中型数据集上从头开始训练时&#xff0c;ViT 的性能仍然不如最先进的 CNN。…

解密长短时记忆网络(LSTM):从理论到PyTorch实战演示

目录 1. LSTM的背景人工神经网络的进化循环神经网络&#xff08;RNN&#xff09;的局限性LSTM的提出背景 2. LSTM的基础理论2.1 LSTM的数学原理遗忘门&#xff08;Forget Gate&#xff09;输入门&#xff08;Input Gate&#xff09;记忆单元&#xff08;Cell State&#xff09;…

【洛谷】P1678 烦恼的高考志愿

原题链接&#xff1a;https://www.luogu.com.cn/problem/P1678 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 将每个学校的分数线用sort()升序排序&#xff0c;再二分查找每个学校的分数线&#xff0c;通过二分找到每个同学估分附近的分数线。 最后…

【Java】对象与类

【Java】对象与类 文章目录 【Java】对象与类1、学习背景2、定义&使用2.1 创建类2.2 创建对象 3、static关键字3.1 修饰变量3.2 修饰方法3.3 修饰代码块3.4 修饰内部类 4、this关键字5、封装特性5.1 访问修饰符5.2 包的概念 6、构造方法7、代码块7.1 普通代码块7.2 成员代码…

信息安全:入侵检测技术原理与应用.(IDS)

信息安全&#xff1a;入侵检测技术原理与应用. 入侵检测是网络安全态势感知的关键核心技术&#xff0c;支撑构建网络信息安全保障体系。入侵是指违背访问目标的安全策略的行为。入侵检测通过收集操作系统、系统程序、应用程序、网络包等信息&#xff0c;发现系统中违背安全策略…

无公网IP内网穿透使用vscode配置SSH远程ubuntu随时随地开发写代码

文章目录 前言1、安装OpenSSH2、vscode配置ssh3. 局域网测试连接远程服务器4. 公网远程连接4.1 ubuntu安装cpolar内网穿透4.2 创建隧道映射4.3 测试公网远程连接 5. 配置固定TCP端口地址5.1 保留一个固定TCP端口地址5.2 配置固定TCP端口地址5.3 测试固定公网地址远程 前言 远程…

【QT5-自我学习-线程qThread移植与使用-通过代码完成自己需要功能-移植小记3】

【QT5-自我学习-线程qThread移植与使用-通过代码完成自己需要功能-移植小记3】 1、前言2、实验环境3、自我总结&#xff08;1&#xff09;文件的编写&#xff08;2&#xff09;信号与槽的新理解&#xff08;3&#xff09;线程数据的传递 4、移植步骤第一步&#xff1a;添加新文…

在Linux系统上安装和配置Redis数据库,无需公网IP即可实现远程连接的详细解析

文章目录 1. Linux(centos8)安装redis数据库2. 配置redis数据库3. 内网穿透3.1 安装cpolar内网穿透3.2 创建隧道映射本地端口 4. 配置固定TCP端口地址4.1 保留一个固定tcp地址4.2 配置固定TCP地址4.3 使用固定的tcp地址连接 Redis作为一款高速缓存的key value键值对的数据库,在…

React组件间数据传递(弹框和高阶组件(HOC)特性实现)

前言 在现代前端开发中&#xff0c;React 已经成为了最受欢迎的 JavaScript 库之一。而在复杂的应用中&#xff0c;不同组件之间的数据传递问题显得尤为关键。在本文中&#xff0c;我们将探讨一种高效的方法&#xff0c;即如何利用弹框和高阶组件特性来实现 React 组件间的数据…

vue3 基础知识 ( webpack 基础知识)05

你好 文章目录 一、组件二、如何支持SFC三、webpack 打包工具四、webpack 依赖图五、webpack 代码分包 一、组件 使用组件中我们可以获得非常多的特性&#xff1a; 代码的高亮&#xff1b;ES6、CommonJS的模块化能力&#xff1b;组件作用域的CSS&#xff1b;可以使用预处理器来…

芯片行业震荡期,数字后端还可以入吗?

自去年开始&#xff0c;芯片行业仿佛进入了动荡期&#xff0c;经历了去年秋招和今年春招的小伙伴都知道&#xff0c;如今找工作有多难。 半导体行业人才缩减、各大厂裁员&#xff0c;在加上高校毕业生人数破千万&#xff0c;对于即将踏入IC这个行业的应届生来说&#xff0c;今…

存储过程的使用

一、实验目的 熟练掌握使用 SQL SERVER 2000 创建和执行存储过程的方法。 熟练掌握存储过程的删除操作。 二、实验准备 1&#xff0e;熟悉 SQL SERVER 2000 设计环境&#xff1b; 2&#xff0e;熟悉存过过程的创建方法、步骤 三、实验内容 1、利用企业管理器或查询分析器…

在线OJ平台项目

一、项目源码 Online_Judge yblhlk/Linux课程 - 码云 - 开源中国 (gitee.com) 二、所用技术与开发环境 1.所用技术: MVC架构模式 (模型&#xff0d;视图&#xff0d;控制器) 负载均衡系统设计 多进程、多线程编程 C面向对象编程 & C 11 & STL 标准库 C Boost 准标…

建议收藏|软考机构推荐看这一篇就够了

需要最近因为软考改革成机考&#xff0c;大家都在问还有没有必要找机构学&#xff1f;本来已经进入自学阶段的考生&#xff0c;也纷纷开始慌张机考改革会不会影响考试难度&#xff1f;今天胖圆给大家总结一下软考要不要报机构&#xff1f;市面上的软考培训机构如何选择&#xf…

高手速成|数据库脚本生成工具

高手速成|数据库脚本生成工具 文章目录 高手速成|数据库脚本生成工具前言1、软件的安装及使用2、建立新工程3、创建Conceptual Data Model&#xff08;概念数据模型&#xff09;4、将E-R图转化为其他数据库模型5、导出DBMS代码&#xff08;Sql执行脚本&#xff09;6、执行sql脚…

【boost网络库从青铜到王者】第六篇:asio网络编程中的socket异步读(接收)写(发送)

文章目录 1、简介2、异步写 void AsyncWriteSomeToSocketErr(const std::string& buffer)3、异步写void AsyncWriteSomeToSocket(const std::string& buffer)4、异步写void AsyncSendToSocket(const std::string& buffer)5、异步读void AsyncReadSomeToSocket(cons…

Java 8 Stream 之 collect() 的奇技淫巧

来源&#xff1a;blog.csdn.net/qq_35387940/ article/details/127008965 前言 正文 第一个小玩法 第二个小玩法 前言 本身我是一个比较偏向少使用Stream的人&#xff0c;因为调试比较不方便。 但是, 不得不说&#xff0c;stream确实会给我们编码带来便捷。 所以还是忍…

python开发环境搭建

1、安装python 下载地址&#xff1a;https://www.python.org/downloads/windows/ 双击安装。 安装完验证&#xff1a; 2、安装IDE 下载地圵&#xff1a;https://www.jetbrains.com/zh-cn/pycharm/download/?sectionwindows 免费版本 3、安装依赖包 在项目的根目录下…