01背包总结

01背包

特点

给定 n n n 种物品,每种物品都有重量 w i w_i wi 和价值 v i v_i vi ,每种物品都只有 一个。

另外,背包容量为 W W W

求解在不超过背包容量的情况下将哪些物品放入背包,才可以使背包中的物品价值之和最大

每种物品只有一 个,要么不放入(0),要么放入(1),因此称之为01背包。

状态表示

f [ i ] [ j ] \large f[i] [j] f[i][j]:从前 i i i 个物品中选,且总体积不超过 j j j 的最大价值。

初始边界条件

f [ 0 ] [ i ] = 0   ( 0 ≤ i ≤ n ) \large f[0] [i]=0\ (0 \le i \le n) f[0][i]=0 (0in)

意思为,从前 0 个物品中选,总体积不超过 i i i 的最大价值。

因为没选任何一个物品所以最大价值为 0。

转移方程

根据选或不选第 i − 1 i - 1 i1 个物品作为区分。

j ≥ v i j \ge v_i jvi 时 : 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][jvi]+wi)

j < v i j < v_i j<vi 时: f [ i , j ] = f [ i − 1 ] [ j ] \large f[i,j]=f[i-1][j] f[i,j]=f[i1][j]

代码

时间复杂度: O ( n m ) O(nm) O(nm)

二维

for (int i = 1; i <= n; i ++ ) {
	for (int j = 1; 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]);
	}
}

一维

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]);
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值