0-1背包问题

问题描述:

        给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为C。问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?(在选择装入背包的物品时,对每种物品i只有两种选择,即装入背包或不装入背包。不能将物品i装入背包多次,也不能只装入部分的物品i。因此,该问题称为0-1背包问题)

算法描述:

        由0-1背包问题的最优子结构性质,我们可以建立m(i, j)的递归表达式如下:


          基于以上讨论,当wi(1≤i≤n)为正整数时,用二维数组m[ ][ ]来存储m(i,j)的相应值,可设计解0-1背包问题的动态规划算法Knapsack如下:

template<class Type>
void Knapsack(Type v, int w, int c, int n, Type** m)
{
	int jMax = min(w[n] - 1, c);
	for (int j = 0; j <= jMax; j++)
         m[n][j] = 0;
	for (int j = w[n]; j <= c; j++)
         m[n][j] = v[n];
	for (int i = n - 1; i > 1; i--) {
		jMax = min(w[i] - 1, c);
		for (int j = 0; j <= jMax; j++)
            m[i][j] = m[i + 1][j];
		for (int j = w[i]; j <= c; j++)
            m[i][j] = max(m[i + 1][j], 
                 m[i + 1][j - w[i]] + v[i]);
	}
		m[1][c] = m[2][c];
		if (c >= w[1])m[1][c] = max(m[1][c], 
                 m[2][c - w[1]] + v[1]);
}
//构造最优解
template<class Type>
void Traceback(Type** m, int w, int c, int n, int x)
{
	for (int i = 1; i < n; i++)
		if (m[i][c] == m[i + 1][c])x[i] = 0;
		else { x[i] = 1; c -= w[i]; }
	x[n] = (m[n][c]) ? 1 : 0;
}

        按上述算法Knapsack计算后,m[1 ][c ]给出所要求的0-1背包问题的最优值。相应的最优解可由算法Traceback计算如下。如果m[1 ][ c]=m[ 2][c ],则x1=0,否则x1=1,当x1=0时,由mm[ 2][c ]继续构造最优解。当x1=1时,由m[ 2][c -w1]继续构造最优解。依次类推,可构造出相应的最优解(x1,x2,···,xn)。 

        时间复杂度:0-1背包问题的动态规划算法的时间复杂度为O(nW),其中n为物品数量,W为背包容量。

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值