010-算法面试必备-背包问题

 * 01背包问题
 * 有一个背包,它的容量为C (Capacity),。
 * 现在有n种不同的物品,编号为0...n-1,
 * 其中每一件物品的重量为w(i),价值为v(i)。
 * 问可以向这个背包中盛放哪些物品,

 * 使得在不超过背包容量的基础上,物品的总价值最大。


分别用一种递归和两种动态规划的形式写了出来,仅供参考

class Solution_BagProblem0712{
	//状态转移:F(C,n)表示将[0..n]为索引的物品填充容量为C的背包所获得最大的价值
	//这里有两种情况:1,如果包含该索引n,这里的条件是C>=w[n],F(C-w[n],n-1) + v[n]
	//             2, 如果不包含索引n,F(C,n-1)
	//             3,这两者取最大的一个
    //终止条件:C==0 return 0;
	//        n == -1 return 0;
	private int getMaxValue(int n,int c,int[]w,int[]v){
		int maxValue=0;
		if(c == 0)return 0;
		if(n == -1)return 0;
		if(c>=w[n]){
			maxValue = getMaxValue(n-1,c-w[n],w,v)+v[n];
		}
		maxValue = Math.max(maxValue,getMaxValue(n-1,c,w,v));
		return maxValue;
	}
	public int getMaxValue(int c,int[]w,int[] v){
		int n = w.length;
		return getMaxValue(n-1,c,w,v);
	}
	public int getMaxValueDy(int c,int[]w,int[]v){  //memo[j][i]表示[0..i-1]填充容量为j的背包所获得的最大的价值
		int n = w.length;
		int[][]memo = new int[c+1][n];
		for(int i = 0;i<n;i++){
			memo[0][i] = 0;
		}
		for(int j= 0;j<=c;j++){
			if(j>= w[0]){
				memo[j][0] =  v[0];     //将索引为0的物品填到
			}
		}
		for(int i = 1;i<n;i++){
			for(int j = 1;j<=c;j++){
				int maxValue = memo[j][i-1];
				if(j>=w[i]){
					maxValue = Math.max(maxValue,memo[j-w[i]][i-1]+v[i]);
				}
				memo[j][i] = maxValue;
			}
		}
		return memo[c][n-1];
	}
	public int getMaxValueDy2(int C,int[] w,int[] v){
		int n = w.length;
		int[] memo = new int[C+1]; //memo[i]表示的填充容量填充容量为i所获得的最大的价值
			//memo[i] memo[i-1],什么关系?
		for(int i = 1;i<=C;i++){    //先对memo[i]赋初值
			memo[i] = i>w[0]?v[0]:0;
		}
		for(int j = 1;j<n;j++){    //n个箱子
			for(int k = 1;k<=C;k++){  //容量为k
				if(k >= w[j])          //当前的权重能够放的下物品j
					memo[k] = Math.max(memo[k],v[j] + memo[k-w[j]]);
			}
		}
		return memo[C];
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值