01背包详解,状态设计,滚动数组优化,通用问题求解

文章目录

  • 0/1背包
    • 前言
    • 一、0/1背包的状态设计
      • 1、状态设计
      • 2、状态转移方程
      • 3、初始状态
      • 4、代码实现
      • 5、滚动数组优化
        • 二维优化为两个一维
        • 二维优化为一个一维,倒序递推
    • 二、0/1背包的通用问题
      • 求最大值
      • 求最小值
      • 求方案数

0/1背包

前言

0/1包问题,作为动态规划问题的经典问题,可以帮助捋顺思维。核心就是有一堆物品,有两个维度的限制,在保证一个维度限制的情况下,使得另一个维度最优。

一、0/1背包的状态设计

有n(n≤100)个物品和一个容量为m(m≤10000)的背包。
第i个物品的容量是c[i],价值是w[i]。现在需要选择一些物品放入包, 总容不能超过背包容量,求能够达到的物品的最大总价值。

以上就是0/1背包问题的完整描述,之所以叫0/1背包,因为每种物品只有一个,可以选择
放入背包或者不放,而0代表不放,1 代表放。

1、状态设计

状态(i, j)表示前i个物品恰好放入容量为j的背包(0≤i<n,0≤j≤m);
令dp表[][]示状态(i, j)下该背包得到的最大价值,即前i个物品恰好放入容量为j的背包所得
到的最大总价值;

2、状态转移方程

列出状态转移方程如下:
d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j ] , d p [ i − 1 ] [ j − c [ i ] ] + w [ i ] ) dp[i][j] = max(dp[i-1][j], dp[i-1][j - c[i]] + w[i]) dp[i][j]=max(dp[i1][j],dp[i1][jc[i]]+w[i])
因为每个物品要么放,要么不放,所以只需要考虑第i个物品放或不放的情况:

1)不放:如果第i个物品不放入容量为j的背包",那么问题转化成求"前i-1 个物品放入容为j的背包"的问题;于不放,所以最大价值就等于"前i-1个物品放入容量为j的背包"的最大价值,即dp[i-1][j];

2)放:如果"第i个物品放入容为j的背包",那么问题转化成求"前i-1个物品放入容量为j-c[j]的背包"的问题;那么此时最大价值就等于"前i-1个物品放入容为j-c[i] 的背包"的最大价值加上放入第i个物品的价值,即dp[i-1][j - c[i]] + w[i]
将以上两种情况取大者,就是我们所求的“前i个物品恰好放入容量为j的背包"的最大价值了。

在这里插入图片描述

3、初始状态

我们发现,当状态在进行转移的时候,dp(i, j)不是来自dp(i - 1 , j),就是来自dp(i - 1 , j - c[i]),所以必然有一个初始状态,而这个初始状态就是(0, i),含义是"前i个物品放入一个容量为0的背包",这个状态下的最大价值为0,即dp[0][i] = 0;

img

4、代码实现

铺垫了那么多,我们来实现一下0/1背包的板子。

//#define N 110
//#define M 1010
//int dp[N][M]{0}, c[N]{0}, w[N]{0}, n, m;
//c[i]为第i个物品的重量,w[i]为第i个物品的价值。n、m分别为物品数和背包容量
for (int i = 1; i <= n; i++)for (int j = 0; j <= m; j++)if (j < c[i])dp[i][j] = dp[i - 1][j];elsedp[i][j] = max(dp[i - 1][j], dp[i - 1][j - c[i]] + w[i]);

5、滚动数组优化

滚动数组优化为递推问题中的常用空间优化手段,如果每次递推都由上一次状态转移那么我们可以将空间降低一个维度。

我们再看状态转移图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

发现每个状态都只跟上一行同一列和上一行左边的状态有关,我们可以开两个一维数组,分别保存上一行和当前行的状态,当然也可以只用一个一维数组然后倒序递推来实现。

二维优化为两个一维

两个一维数组一个保存上一行的状态一个保存当前行状态即可。

#define N 110
#define M 1010
int dp1[M]{0}, dp2[M]{0}, c[N]{0}, w[N]{0}, n, m;
for (int i = 1; i <= n; i++)cin >> c[i] >> w[i];
for (int i = 1; i <= n; i++)
{for (int j = 0; j <= m; j++)if (j < c[i])dp2[j] = dp1[j];elsedp2[j] = max(dp1[j], dp1[j - c[i]] + w[i]);memcpy(dp1, dp2, sizeof(dp1));
}
cout << dp2[m];
二维优化为一个一维,倒序递推

即然每次状态都只由上一行当前列和当前行左侧列转移,我们发现两个一维优化方案中,dp1其实是也可以优化掉的,假如只剩下一个一维数组dp,如果我们正序递推会怎样?

初始时dp中存储上一次状态转移的数据,如果正序递推则导致我们状态转移需要上一次状态但是由于正序递推覆盖了左侧内容,就无法获取上一次状态了,所以我们选择逆序递推:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

#define N 110
#define M 1010
int dp[M]{0}, dp2[M]{0}, c[N]{0}, w[N]{0}, n, m;
for (int i = 1; i <= n; i++)cin >> c[i] >> w[i];
for (int i = 1; i <= n; i++)
{for (int j = m; j >= c[i]; j--)dp[j] = max(dp[j], dp[j - c[i]] + w[i]);
}
cout << dp[m];

二、0/1背包的通用问题

求最大值

原题链接

[P1048 NOIP2005 普及组] 采药 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

01背包板子题,读完数据跑一遍板子,输出数据即可。

#include <iostream>
#include <cstring>
#include <vector>
#include <functional>
#include <algorithm>
#include <cmath>
#include <functional>
#include <climits>
#include <bitset>
#include <stack>
#include <cstring>
using namespace std;
#define N 110
#define M 1010
int dp[M]{0}, c[N]{0}, w[N]{0}, n, m;
int main()
{ios::sync_with_stdio(false);cin.tie(nullptr), cout.tie(nullptr);cin >> m >> n;for (int i = 1; i <= n; i++)cin >> c[i] >> w[i];for (int i = 1; i <= n; i++){for (int j = m; j >= c[i]; j--)dp[j] = max(dp[j], dp[j - c[i]] + w[i]);}cout << dp[m];return 0;
}

[P1060 NOIP2006 普及组] 开心的金明 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

同样是01板子题,只不过物品价值变成了重量乘价值

#include <iostream>
#include <cstring>
#include <vector>
#include <functional>
#include <algorithm>
#include <cmath>
#include <functional>
#include <climits>
#include <bitset>
#include <stack>
#include <cstring>
using namespace std;
#define N 30010
#define M 100000000
int dp[M]{0}, c[N]{0}, w[N]{0}, n, m;
int main()
{ios::sync_with_stdio(false);cin.tie(nullptr), cout.tie(nullptr);cin >> m >> n;for (int i = 1; i <= n; i++)cin >> c[i] >> w[i], w[i] *= c[i];for (int i = 1; i <= n; i++){for (int j = m; j >= c[i]; j--)dp[j] = max(dp[j], dp[j - c[i]] + w[i]);}cout << dp[m];return 0;
}

P3985 不开心的金明 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

在不考虑内存的情况下显然是一道01背包板子题,但是你这个1e9的背包内存肯定会爆,内存不爆你时间复杂度也会爆,但是金明妈妈限制了物品重量极差不超过3(感谢金明妈妈!!!!),我们就可以将物品重量离散化到1,2,3,4上,即我们记录最小重量mi,再令每个重量减去(mi - 1),这样物品重量就变为了1,2,3,4

由于物品数目最多100,所以物品总重量最大也就400,我们离散化后再去跑01背包的板子即可

但是!!!

有一个问题,你怎么根据离散化后的重量计算离散化前的重量呢?看我们的板子

for (int i = 1; i <= n; i++)
{for (int j = sum; j >= c[i]; j--)dp[j] = max(dp[j], dp[j - c[i]] + w[i]);
}

此时j为离散化后的重量了,你怎么确定你上面的状态方程就合法呢?如果一共给了m的空间,你此时的j对应实际重量为j + cnt * mi,cnt为装的物品数目,故而我们需要给dp增加一个维度来记录装入的物品数目

dp[i][j]就代表容量i装入了j个物品的最大价值,此时装入总重量不超过i + j * mi,(不超过是因为i可能大于j个物品的离散重量)

这样一来我们的空间复杂度只有1e2量级,时间复杂度只有1e6量级

代码如下:

#include <iostream>
#include <cstring>
#include <vector>
#include <functional>
#include <algorithm>
#include <cmath>
#include <functional>
#include <climits>
#include <bitset>
#include <stack>
#include <cstring>
using namespace std;
#define N 110
#define M 550
int dp[M][N]{0}, c[N]{0}, w[N]{0}, n, m, mi = INT_MAX, sum = 0, ans = 0;
int main()
{ios::sync_with_stdio(false);cin.tie(nullptr), cout.tie(nullptr);cin >> n >> m;for (int i = 1; i <= n; i++)cin >> c[i] >> w[i], mi = min(mi, c[i]);mi--;for (int i = 1; i <= n; i++)c[i] -= mi, sum += c[i];for (int i = 1; i <= n; i++){for (int j = sum; j >= c[i]; j--)for (int k = (m - j) / mi ; k >= 1; k--)ans = max(ans, dp[j][k] = max(dp[j][k], dp[j - c[i]][k - 1] + w[i]));}cout << ans;return 0;
}

求最小值

原题链接

[P1049 NOIP2001 普及组] 装箱问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

本质还是求最大值。

在本题内,重量就是体积,价值也是体积,我们求出能装的最大体积,容量减去最大体积就是答案。

#include <iostream>
#include <cstring>
#include <vector>
#include <functional>
#include <algorithm>
#include <cmath>
#include <functional>
#include <climits>
#include <bitset>
#include <stack>
#include <cstring>
using namespace std;
#define N 50
#define M 20010
int dp[M]{0}, c[N]{0}, w[N]{0}, n, m;
int main()
{ios::sync_with_stdio(false);cin.tie(nullptr), cout.tie(nullptr);cin >> m >> n;for (int i = 1; i <= n; i++)cin >> c[i];for (int i = 1; i <= n; i++){for (int j = m; j >= c[i]; j--)dp[j] = max(dp[j], dp[j - c[i]] + c[i]);}cout << m - dp[m];return 0;
}

求方案数

原题链接

P1164 小A点菜 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

对于本道题我们的dp[i][j]就变成了j元恰好买i道菜的方案数

对于初始状态即0元购0菜方案为1,其他0元购都是0

那么我们同样对于每道菜可以选择买或不买,可以选择用j元恰好买i - 1道菜也可以选择用j元恰好买i道菜,那么转移方程就变成了

dp[i][j] = dp[i - 1][j] + dp[i - 1][j - c[i]]

#include <iostream>
#include <cstring>
#include <vector>
#include <functional>
#include <algorithm>
#include <cmath>
#include <functional>
#include <climits>
#include <bitset>
#include <stack>
#include <cstring>
using namespace std;
#define N 110
#define M 10010
int dp[M]{0}, c[N]{0}, w[N]{0}, n, m;
int main()
{ios::sync_with_stdio(false);cin.tie(nullptr), cout.tie(nullptr);cin >> n >> m;for (int i = 1; i <= n; i++)cin >> c[i];dp[0] = 1;for (int i = 1; i <= n; i++){for (int j = m; j >= c[i]; j--)dp[j] += dp[j - c[i]];}cout << dp[m];return 0;
}

https://www.luogu.com.cn/problem/P3985)

416. 分割等和子集

剑指 Offer II 101. 分割等和子集

1262. 可被三整除的最大和

这道题目如何转化为0/1背包问题呢,我们这里的背包容量是3,因为我们对3取余只有0,1,2三种情况,

那么我们的每个数字对于3取余的结果就是它的重量,其值就是价值

只不过我们以往放入背包里面还要考虑背包已满的情况,在这里便不用了,因为我们放入一个数字后,和对3取余结果仍在3以内,只不过我们最后要的是对三取余为0的最大和罢了

dp[ i ] [ j ]代表前i个数字放入对取余为j的背包里面的最大和,dp[ i ] [ i ] = max(dp[ i - 1] [ (j - nums[i] % 3) % 3 ] + nums[ i ] , dp[i - 1] [ j ])

但对于j - nums[i] % 3) % 3会有负值,我们可以改为

dp[ i ] [(nums[i] % 3 + j) % 3] = max(dp[i - 1] [ j ] + nums[ i ] , dp[ i - 1 ] [(nums[i] % 3 + j) % 3] );

显然我们可以用滚动数组优化为一维空间,但是我们本题dp虽然从i - 1转移,但转移的容量未必比新容量小,所以每次要提前用一个prev数组来保存dp数组的旧值,一共需要三个元素的空间

如此一来,有递推

dp[(nums[j] % 3 + i) % 3] = max(prev[i] + nums[j] , dp[(nums[j] % 3 + i) % 3]);

代码如下:

class Solution {
public:int maxSumDivThree(vector<int>& nums) {int n = nums.size();vector<int> dp{0 , INT_MIN , INT_MIN};for(int j = 0 ; j < n ; j++){vector<int>prev(dp);for(int i = 0 ; i < 3 ; i++)dp[(nums[j] % 3 + i) % 3] = max(prev[i] + nums[j] , dp[(nums[j] % 3 + i) % 3]);}return dp[0];}
};

1774. 最接近目标价格的甜点成本

这个0/1背包问题呢,没有定死背包的容量,而是给我们物品,不限制容量,让你找一个方案使得装的物品的总重量最接近给定的target

那么我们的关注点在于对于一个容量我们能不能装

所以我们只要找到方案价格上限作为我们的背包容量,然后套用模板枚举即可

方案上限对应target取上限10000

对于方案我们无非有三种情况

只选基料

上限为10000

基料加一个辅料

base + toppingCosts - 10000 <= 10000 - base 也就是大于一万方案可选的条件

对于2 * x + y <= C求x + y最值,用高中数学在直角坐标系上面画一下就出来了

x + y <= 20000故上限为20000

基料加两个辅料

base + toppingCosts * 2 - 10000 <= 10000 - base

同样的解得x + 2 * y <= 10000

取大者20000,故上限为20000

接下来就是0/1背包模板了,只不过我们要先把辅料给放进去

代码如下:

class Solution {
public:
const int maxn = 20000;int closestCost(vector<int>& baseCosts, vector<int>& toppingCosts, int target) {//背包容量为20000bitset<20001> can;for(auto x : baseCosts)can[x] = 1;toppingCosts.insert(toppingCosts.end() , toppingCosts.begin() , toppingCosts.end());for(auto x : toppingCosts)for(int i = maxn ; i >= x ; i--)can[i] = can[i] || can[i - x];int res = maxn;for(int i = maxn ; i >= 0 ; i--)if(can[i] && abs(target - i) <= abs(target - res)){res = i;}return res;}
};

2212. 射箭比赛中的最大得分

F1:0/1背包

这道题联系到0/1背包是很不容易的,Bob能够射的箭的数量numArrows是给定了的,我们每次可以射可以不射,最后求最大得分,这其实就有点0/1背包的意思了

我们定义状态dp[ i ] [ j ]表示前i个区域,射j支箭可以获得的最大得分

而我们能够射的条件是j >= aliceArrows[i],这个时候我们选择射aliceArrows[i] + 1支箭,保证射的最少还能拿分

当j >= aliceArrows[i]时

dp[i][j] = max(dp[i - 1] [j] , dp[i - 1] [j - a - 1] + i);

否则

dp[i] [j] = dp[i - 1] [j];

按照套路我们可能会想到去滚动数组优化,但是这道题目要求返回个区域射出箭的数目,所以我们还要遍历每个区域的得分,通过判断和前一个区域的最大得分的比较来判断是否在这个区域射了箭,其实就是一个路径恢复问题

如果这个区域射了箭,那么显然射aliceArrows[i] + 1支,我们箭的余量减去aliceArrows[i] + 1,这样倒序枚举一直枚举到第一个区域结束,最后剩余箭的数目就是第一个区域射的数目

代码如下:

class Solution {
public:vector<int> maximumBobPoints(int numArrows, vector<int>& aliceArrows) {vector<vector<int>> dp(12 , vector<int>(numArrows + 1 , 0));vector<int> ret(12 , 0);for(int i = 1 ; i < 12 ; i++){int a = aliceArrows[i];for(int j = 1 ; j <= numArrows ; j++){if(j >= a + 1)dp[i][j] = max(dp[i - 1][j] , dp[i - 1][j - a - 1] + i);elsedp[i][j] = dp[i - 1][j];}}    for(int i = 11 ; i >= 1 ; i--){if(dp[i][numArrows] > dp[i - 1][numArrows]){ret[i] = aliceArrows[i] + 1;numArrows -= ret[i];}}ret[0] = numArrows;return ret;}
};

F2:二进制枚举

1049. 最后一块石头的重量 II

本题可能想到是背包问题,但是会很难往背包上面去靠,我们要最后留下来的石头的最小重量,其实可以等效为两堆石头重量的最小差值,为什么呢?

根据我们题目的规则,每次拿出两个石头让他们的重量相减,如此重复,到最后一步只剩下两个石头,然后质量相减变为一个石头,我们仔细思考会发现假如有n块石头,最后剩下的重量其实是总质量减去n - 1块石头的重量和一块石头的部分重量,那么自然可以等效为两堆石头的质量相减,当然我们要保证两堆石头尽可能的接近sum/2,这样不会出现一堆石头过于重,使得相减之后其实剩余的重量其实还可以进行几块石头间的相减

那么假如我们有了两堆石头,保证了二者都尽可能的接近sum / 2,一堆是x,另一堆是sum - x,那么二者对于sum的差的绝对值都是2 / sum - x

而我们要的结果其实是sum - 2 * x

这样就可以等效为若干块总重sum重量的石头能往容量为sum / 2的背包里面放的最大重量

dp[ i ] [ j ] = max(dp[ i - 1 ] [ j ] , dp[ i - 1 ] [ j - stones[i] ])(令人熟悉的模板)

利用滚动数组优化则

dp[i] = max(dp[i - x] + x , dp[i]);

代码如下

class Solution {
public:int lastStoneWeightII(vector<int>& stones) {int sum = accumulate(stones.begin() , stones.end() , 0);int target = sum / 2;vector<int> dp(target + 1);for(auto x : stones)for(int i = target ; i >= x ; i--){dp[i] = max(dp[i - x] + x , dp[i]);}return sum - 2 * dp[target];}
};

474. 一和零

如何把问题转化为一个0/1背包问题呢?

这道题目与以往的0/1背包不同的地方是背包的维度是一个二维的背包

题目给我们规定了0和1的限制数目m和n,就是背包两个维度的容量,我们不妨定义dp[ i ] [ j ] [ k ]为前i个字符串放到总量为j个0和k个1中的最大字符串数量

我们只需要遍历字符串数组,然后枚举两个维度容量(顺序无所谓),然后套用模板即可

又因为根据滚动数组优化我们可以只保留容量维度,优化去i这个维度,于是有递推:

dp[ i ] [ j ] = max(dp[ i ] [ j ] , dp[ i - p ] [ j - q] + 1),(p和q分别为当前枚举字符串中0和1的个数)

class Solution {
public:int findMaxForm(vector<string>& strs, int m, int n) {int sz = strs.size();vector<vector<int>> dp(m + 1 , vector<int>(n + 1));for(auto& x : strs){int p = 0 , q = 0;for(auto ch : x)if(ch == '0')p++;elseq++;for(int i = m ; i >= p ; i--){for(int j = n ; j >= q ; j--){dp[i][j] = max(dp[i][j] , dp[i - p][j - q] + 1);}}}return dp[m][n];}
};

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

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

相关文章

Python通过telnet批量管理配置华为交换机

名称&#xff1a;Python通过telnet批量管理配置华为交换机 测试工具&#xff1a;ensp, Visual Studio Code &#xff0c; Python3.8环境 时间&#xff1a;2023.12.23 个人备注&#xff1a;在NB 项目中&#xff0c;可以批量登录修改交换机配置&#xff0c;以此满足甲方爸爸的…

【Linux基础开发工具】gcc/g++使用make/Makefile

目录 前言 gcc/g的使用 1. 语言的发展 1.1 语言和编译器自举的过程 1.2 程序翻译的过程&#xff1a; 2. 动静态库的理解 Linux项目自动化构建工具-make/makefile 1. 快速上手使用 2. makefile/make执行顺序的理解 前言 了解完vim编辑器的使用&#xff0c;接下来就可以尝…

drawio绘制组织架构图和树形图

drawio绘制组织架构图和树形图 drawio是一款强大的图表绘制软件&#xff0c;支持在线云端版本以及windows, macOS, linux安装版。 如果想在线直接使用&#xff0c;则直接输入网址draw.io或者使用drawon(桌案), drawon.cn内部完整的集成了drawio的所有功能&#xff0c;并实现了云…

【一起学Rust | 框架篇 | Tauri2.0框架】Tauri2.0环境搭建与项目创建

文章目录 前言一、搭建 Tauri 2.0 开发环境二、创建 Tauri 2.0 项目1.创建项目2.安装依赖4. 编译运行 三、设置开发环境四、项目结构 前言 Tauri在Rust圈内成名已久&#xff0c;凭借Rust的可靠性&#xff0c;使用系统原生的Webview构建更小的App 以及开发人员可以灵活的使用各…

IDEA 中 Tomcat 日志乱码

1、服务器输出乱码 修改 File -> settings -> Editor -> General ->Console 中&#xff0c;utf-8改为GBK&#xff0c;反之改成utf-8 2、Tomcat Localhost Log 或者 Tomcat Catalina Log乱码 进入Tomcat 中的conf文件中的logging.properties 哪个有问题改哪个&…

虚拟机的下载、安装(模拟出服务器)

下载 vmware workstation&#xff08;收费的虚拟机&#xff09; 下载vbox 网址&#xff1a;Oracle VM VirtualBox&#xff08;免费的虚拟机&#xff09; 以下选择一个下载即可&#xff0c;建议下载vbox&#xff0c;因为是免费的。安装的时候默认下一步即可&#xff08;路径最好…

【数据安全】Java AES加密和解密

自我介绍 做一个简单介绍&#xff0c;酒架年近48 &#xff0c;有20多年IT工作经历&#xff0c;目前在一家500强做企业架构&#xff0e;因为工作需要&#xff0c;另外也因为兴趣涉猎比较广&#xff0c;为了自己学习建立了三个博客&#xff0c;分别是【全球IT瞭望】&#xff0c;【…

Kubernetes 架构原则和对象设计

什么是 Kubernetes Kubernetes 是谷歌开源的容器集群管理系统 • 基于容器的应用部署、维护和滚动升级&#xff1b; • 负载均衡和服务发现&#xff1b; • 跨机器和跨地区的集群调度&#xff1b; • 自动伸缩&#xff1b; • 无状态服务和有状态服务&#xff1b; • 插件机制…

fba海派和传统海运的区别,亚马逊 FBA货物包装技巧—站斧浏览器

fba海派和传统海运的区别 1、美国FBA海派是什么&#xff1f; 美国FBA海派即将商品通过海洋运输的方式运送到美国亚马逊FBA仓库的服务。这种方式主要适用于大批量或大件商品&#xff0c;因为相比其他物流方式&#xff0c;海派具备成本低和运载量大的优势。 2、传统海运是什么…

编译opencv和opencv_contrib

1 下载源码 下载opencv源码https://github.com/opencv/opencv 下载opencv源码https://github.com/opencv/opencv_contrib 2 开始编译 构建需要下载ffmpeg的包&#xff0c;cmake构建时会自动下载&#xff0c;但是比较满&#xff0c;这里可以从下面链接直接下载 https://downloa…

ECMAScript基础入门:从语法到应用

在此之前我以及发布过关于JavaScript基础知识点大家也可以参考 大家有关于JavaScript知识点不知道可以去 &#x1f389;博客主页&#xff1a;阿猫的故乡 &#x1f389;系列专栏&#xff1a;JavaScript专题栏 &#x1f389;ajax专栏&#xff1a;ajax知识点 &#x1f389;欢迎关注…

C++ Qt开发:Charts折线图绘制详解

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍QCharts折线图的常用方法及灵活运用。 折线图…

C++ map和vector向量使用方法

C map用法 C 中 map 提供的是一种键值对容器&#xff0c;里面的数据都是成对出现的,如下图&#xff1a;每一对中的第一个值称之为关键字(key)&#xff0c;每个关键字只能在 map 中出现一次&#xff1b;第二个称之为该关键字的对应值。 map的使用 需要导入头文件 #include …

采用线性插值的方法 在n个坐标点的基础上 准备添加一个坐标点p 根据给出p的横坐标 计算出p的纵坐标 np.interp()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 采用线性插值的方法 在n个坐标点的基础上 准备添加一个坐标点p 根据给出p的横坐标 计算出p的纵坐标 np.interp() [太阳]选择题 下列选项正确的是&#xff1a; import numpy as np x np.arra…

[架构之路-264]:个性特征 - 到底什么才是工程师文化?

目录 前言&#xff1a; 一、三种类型的商业公司与生存法则 &#xff08;1&#xff09;运营或销售驱动型公司 &#xff08;2&#xff09;产品驱动型公司 &#xff08;3&#xff09;技术驱动型公司 二、工程师文化特征解读1 三、工程师文化特征解读2 &#xff08;1&#…

解决Unity物体速度过快无法进行碰撞检测(碰撞检测穿透)

解决Unity物体速度过快无法进行碰撞检测&#xff08;碰撞检测穿透&#xff09; 一、解决碰撞检测穿透方法一Collision Detection碰撞检测总结&#xff1a; 二、解决碰撞检测穿透方法二 一、解决碰撞检测穿透方法一 首先我们知道只要是跟碰撞相关的基本都是离不开刚体 Rigidbod…

八大排序算法@直接插入排序(C语言版本)

目录 直接插入排序概念算法思想代码实现核心算法&#xff1a;直接插入排序的算法实现&#xff1a; 特性总结 直接插入排序 概念 算法思想 把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中&#xff0c;直到所有的记录插入完为止&#xff0c;得到一个新…

「C/C++ 01」 深拷贝和浅拷贝

目录 一、概念 1. 浅拷贝 2. 深拷贝 3. 深浅拷贝问题 4. 总结 二、在C的类中实现深拷贝 1. 拷贝构造函数 中实现深拷贝 a. 自己开辟一个新空间&#xff0c;然后将内容拷贝到新空间 b. 借助构造函数来实现深拷贝 2. operator 中实现深拷贝 a. 自己开辟一个新空间&#xff0c;…

One Wire协议应用篇(c语言板)

一.项目简介 利用DS18B20实时检测温度并显示在LCD1602显示屏上&#xff0c;同时可以通过K1,K2,K3,K4设置最高温度和最低温度利用AT24C02可以实现掉电不丢失&#xff0c;最后当检测温度大于或小于最高温时&#xff0c;会在LCD1602显示屏上显示OV:H或OV:L。 二.准备材料 AT89C52、…

ESP32+LVGL笔记(6)-把712k的一二级汉字字库放在SPIRAM

文章目录 1.字库制作2.字库烧录到ESP32-S3的flash2.1 配置好分区文件2.2 汉字库文件烧录到ESP32的flash 3.将字库从 flash 拷贝到 SPIRAM3.1 工程配置中有关 SPIRAM 部分3.2 将汉字库从flash拷贝到SPIRAM的代码3.3 在进入lvgl之前调用函数 copyHZK_from_flash_to_SPIRAM 在前面…