01背包的一维数组优化

普通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]

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值