普通01背包
for (int i = 1; i <= quantity; i ++) {
for (int j = 1; j <= capacity; j++) {
if ( j < cost[i] ) dp[i][j] = dp[i - 1][j];
else dp[i][j] = max( dp[ i - 1 ][ j ], dp[ i - 1 ][ j - cost[i] ] + value[i] );
}
}
滚动数组优化( 优化空间复杂度从O(n*m) ---> O(m) )
采用一个一维数组来存储dp[j]来存储
实际上就是将之前二位数组的第i-1层覆盖到了第i层
其中dp数组的大小为背包的容量大小
相关含义
j的含义为背包容量
dp[j]的含义为在背包容量为j的情况下前i个物品所能获得的最大收益
递推公式
dp[j] = max( dp[j], dp[ j - cost[i] ] + value[i] );
在上述的dp递推公式中,等于号前面的dp[j]等价于没有经过优化的01中的dp[i][j]
max函数中的dp[j]等价于dp[i-1][j]
关于初始化
dp数组的初始化一定要和它的含义相吻合
首先在容量为0时所获得的最大收益必然为零,所以dp[0] = 0;
其次,如若每个物品的收益均大于0,则将其他部分也初始化为0;
否则,将其他部分都初始化为负无穷,这是为了在遍历中取到正确的值而不是被初始值覆盖了
遍历顺序
memset(dp, 0, sizeof dp); for(int i = 1; i<= quantity; i ++){ for(int j = capacity; j >= cost[i]; j --){ dp[j] = max( dp[j], dp[ j- cost[i] + value[i] ] ); } }
因为小于cost[i]的部分都是上一层i-1的,所以就不用覆盖
至此,一维数组优化完成答案即为dp[m]