01背包问题

一、递归解决背包问题

暴力递归,穷举出所有的可能性,在检索完所有物品,即index=nums.length时候决定是否更新最大值
1、当物品体积小于等于当前背包容量,选择放或者不放
2、当物品体积大于,只能选择不放该物品

//递归解决背包问题
	public int getMaxValue(int[] weight, int[] value, int capacity) {
		int index = 0;
		int max = Integer.MIN_VALUE;
		max = process(weight, value, index, 0, 0, capacity, max);
		return max;
	}
	
	/**
	 * 
	 * @param weight 质量数组
	 * @param value	价值数组
	 * @param index 当前位置
	 * @param prevalue 之前背包价值
	 * @param precapacity 之前背包容量
	 * @param capacity 背包总容量
	 * @param max 最大值
	 * @return
	 */
	public int process(int[] weight, int[] value, int index, int prevalue, int precapacity, int capacity, int max) {
		if (index == weight.length) {
			max = Math.max(max, prevalue);
			return max;
		}
		//当前物品体积小于等于背包容量
		if (precapacity + weight[index] <= capacity) {
			max = process(weight, value, index + 1, prevalue + value[index], precapacity + weight[index], capacity,
					max);
		}
		//
		max = process(weight, value, index + 1, prevalue, precapacity, capacity, max);
		return max;

	}

二、动态规划

1、res[i][j]表示当前物品为i,当前背包容量为j的最大价值
2、res[i-1][j]代表的就是不将这件物品放入背包,而res[i-1][j-weight[i-1]]+value[i-1]则是代表将第i件放入背包之后的总价值,比较两者的价值,得出最大的价值存入现在的背包之中
3、流程

if(当前物品体积大于容量) {
		res[i][j] = res[i-1][j];//当前背包最大价值等于前一件物品放入背包的价值
}else {
		//当前物品放与不放的较大价值
		res[i][j] = Math.max( res[i-1][j],res[i-1][j-weight[i-1]]+value[i-1]);
}

在这里插入图片描述

//动态规划解决背包问题
	public int getMaxValueDP(int[] weight, int[] value, int capacity) {
		int num = weight.length;
		//一维表示物品i,二维表示背包容量
		//w[i]>j ,则 m[i][j] = m[i-1][j],无法放下当前物品,因此最大价值为前一个物品最大价值
		//w[i]>j,则m[i][j] = Math.max( m[i-1][j],m[i][j-weight[i]]+v[i]),如果能够放下当前物品,则会选择放或者不放,最终选择较大值
		int[][] res = new int[num+1][capacity+1];
		for (int i = 1; i < res.length; i++) {
			for (int j = 0; j < res[0].length; j++) {
				if(weight[i-1]>j) {
					res[i][j] = res[i-1][j];
				}else {
					res[i][j] = Math.max( res[i-1][j],res[i-1][j-weight[i-1]]+value[i-1]);
				}
			}
		}
		return res[num][capacity];
	}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值