算法-动态规划3组合问题-0/1背包问题

算法-动态规划3-0/1背包问题

动态规划与分治法类似,都是把大问题拆分成小问题,通过寻找大问题与小问题的递推关系,解决一个个小问题,最终达到解决原问题的效果。但不同的是,分治法在子问题和子子问题等上被重复计算了很多次,而动态规划则具有记忆性,通过填写表把所有已经解决的子问题答案纪录下来,在新问题里需要用到的子问题可以直接提取,避免了重复计算,从而节约了时间,所以在问题满足最优性原理之后,用动态规划解决问题的核心就在于填表,表填写完毕,最优解也就找到。

0/1背包问题:
给定n个重量为{w1, w2, … ,wn}、价值为{v1, v2, … ,vn}的物品和一个容量为C的背包,求这些物品中的一个最有价值的子集,并且要能够装到背包中。

0/1背包问题可以看作是决策一个序列(x1, x2, …, xn),对任一变量xi的决策是决定xi=1还是xi=0。在对xi-1决策后,已确定了(x1, …, xi-1),在决策xi时,问题处于下列两种状态之一:
(1)背包容量不足以装入物品i,则xi=0,背包不增加价值;
(2)背包容量可以装入物品i,则xi=1,背包的价值增加了vi;

这两种情况下背包价值的最大者应该是对xi决策后的背包价值。令V(i, j)表示在前i(1≤i≤n)个物品中能够装入容量为j(1≤j≤C)的背包中的物品的最大值,则可以得到如下动态规划函数:

V(i, 0)= V(0, j)=0 ;
在这里插入图片描述

还有足够的容量可以装该商品,但装了也不一定达到当前最优价值,所以在装与不装之间选择最优的一个,即V(i,j)=max{V(i-1,j),V(i-1,j-w(i))+v(i)}

在这里插入图片描述
然后一行一行的填表:

  • 如i=1,j=1,w(1)=2,v(1)=3,有j<w(1),故V(1,1)=V(1-1,1)=0;
  • 又如i=1,j=2,w(1)=2,v(1)=3,有j=w(1),故V(1,2)=max{ V(1-1,2),V(1-1,2-w(1))+v(1) }=max{0,0+3}=3;
  • 如此下去,填到最后一个,i=4,j=8,w(4)=5,v(4)=6,有j>w(4),故V(4,8)=max{ V(4-1,8),V(4-1,8-w(4))+v(4) }=max{9,4+6}=10……

所以填完表如下图:
在这里插入图片描述
设n个物品的重量存储在数组w[n]中,价值存储在数组v[n]中,背包容量为C,数组V[n+1][C+1]存放迭代结果,其中V[i][j]表示前i个物品装入容量为j的背包中获得的最大价值,数组x[n]存储装入背包的物品,动态规划法求解0/1背包问题的算法如下:
代码:

int KnapSack(int w[], int v[], int n, int C) {
	for (int i = 0; i <= n; i++) {	//初始化第0列
		V[i][0] = 0;
	}
	for (int j = 0; j <= C; j++) {	//初始化第0行
		V[0][j] = 0;
	}

	for (int i = 1; i <= n; i++) {	//计算第i行,进行第i次迭代
		for (int j = 1; j <= C; j++) {
			if (j < w[i]) {
				V[i][j] = V[i - 1][j];
			}
			else {
				V[i][j] = max(V[i - 1][j], V[i - 1][j - w[i]] + v[i]);
			}
		}
	}
	for (int j = C, int i = n; i > 0; i--) {	//求装入背包的物品
		if (V[i][j] > V[i - 1][j]) {
			x[i] = 1;
			j = j - w[i];
		}
		else {
			x[i] = 0;
		}
	}
	return V[n][C];		//返回背包取得的最大价值
}

在该算法中,第一个for循环的时间性能是O(n),第二个for循环的时间性能是O(C),第三个循环是两层嵌套的for循环,其时间性能是O(n×C),第四个for循环的时间性能是O(n),所以,算法6.3的时间复杂性为O(n×C)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值