小工具知识网

当前位置: 首页 > 行业知识 > 卡玛网● 46. 携带研究材料 ● 01背包问题,你该了解这些! 滚动数组 力扣● 416. 分割等和子集

行业知识

卡玛网● 46. 携带研究材料 ● 01背包问题,你该了解这些! 滚动数组 力扣● 416. 分割等和子集

2026-10-21 17:43:43 来源:互联网转载

开始背包问题,���握0-1背包和完全背包即可,注:0-1背包是完全背包的基础。

0-1背包问题:有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。下面是n=4的例子:

如果用穷举方法,应该使用回溯法,那么每个物件都有放一个和不放两种选择,所以回溯的时间复杂度是O(2^n),达到指数级。所以要使用动态规划。

以这个例题来进行二维dp数组和一维dp数组的动规五部曲:背包最大重量为4。物品为:

重量价值
物品0115
物品1320
物品2430

问背包能背的物品最大价值是多少?

 

● 二维dp数组

1. 确定动规数组元素的含义。使用的是二维数组 dp[i][j]:从物品[0,i]范围内随便选择,放进容量为j的背包里,dp[i][j]是背包的最大价值。如下图所示:

2. 确定递推公式。我们可以根据两种方式得到dp[i][j],两种方式对应两种情况,其实dp[i][j]就是取这两种情况的最大值。

①不放物品 i。如果物品i放进重量为j的背包会超重,那么不能把i放进去,所以重量设定为j的话,从[0,i-1]选择和从[0,i]选择的最大价值是一样,所以 dp[i][j] = dp[i-1][j] 。

②放物品 i。如果不会超重,可以放进去。物品 i 放进去,背包最大重量为 j ,还没有放进去物品 i 的时候,背包的最大重量为 j - weight[i] ,数量为i-1,所以这时背包的最大价值为 dp[ i-1 ][ j - weight[i] ]。加入物品 i ,背包价值 dp[i][j] 就为 dp[ i-1 ][ j - weight[i] ] + value[i] 。

所以dp[i][j]= max ( dp[i-1][j] , dp[ i-1 ][ j - weight[i] ] + value[i] )。

必须牢记dp[i][j]的含义。

3. 如何初始化。

在上图里面,背包重量j为0的时候,什么也不能放进去,所以这一列肯定都是0。

物品 0 那一行,只能选择物品 0 自己,所以背包重量 j >=物品 0 的重量对应的表格都应该填上物品 0 的价值15.所以初始化后:

4. 遍历顺序。 根据上表,第一行第一列已经初始化,所以 i 应该从1到2,j 从 0 到背包容量4。是先行还是先列呢,其实都一样。先每个物品那一行统计完更好理解一些,但是先列也是从上往下走的,到一个元素的时候,左上角(包括正上方)的dp[i][j]都已经统计完成,所以都可以。背包问题里,两个for循环的先后循序是非常有讲究的。

5. 打印dp数组。

最后的结果就是返回dp[2][4]。

做题巩固一下:

题目链接46. 携带研究材料:题目链接

和上面例题的分析过程一样,使用二维dp数组,代码如下:

void maxValue(){    int m,begweight;//M 代表物品的种类数,begweight是背包容量    cin>>m>>begweight;    vector weight(m);    vector value(m);    //读取重量和价值    for(int i=0;i>weight[i];    }    for(int i=0;i>value[i];    }    //注意行列数    vector dp(m,vector(begweight+1,0));    //初始化    for(int j=0;j

上一篇:揭秘崞的正确读音,发音与含义全解析

下一篇:电脑反应快慢跟主机什么有关