算法.动态规划.01背包问题 (Java,递归)

前提

01背包 = 完全背包 + 物品个数控制

完全背包与01背包不同就是: 完全是每种物品可以有无限多个,01背包每种物品只有一个,放进去就没有了。所以代码也是从 完全背包的基础上添加 物品的个数控制。

完全背包参考:算法.动态规划.完全背包问题 (Java,递归)icon-default.png?t=M1H3https://blog.csdn.net/weixin_42754896/article/details/123068850

01背包问题

在N个物品取出若干件放在容量为W的背包里,每个物品的体积为W1,W2……Wn(Wi为整数),与之相对应的价值为P1,P2……Pn(Pi为整数)。
求背包能够容纳的最大价值。
说明:每个东西只有一个,装进去就没有了

穷举画图

东西编号 :   D1  D2  D3  D4
体积W  :   2   3   4   5
价值V  :   3   4   5   6
背包体积W:8


假设有两个东西:D1 D2 D3,每次选择都从剩下的选择,直到包里装不下东西(根据体积来算,或者拿不了(根据重量))。
  		    F(W)           
  	 D1      D2       D3			---- 第一次选择
   D2   D3  D1  D3   D1  D2			---- 第二次选择
   D1   D2  D3  D1   D3  D1			---- 第三次选择
……  


F(8): 装满体积8的最大价值
D1.W: D1东西的体积
D2.V: D2东西的价值
F(W) = Max( F(W-D1.W) + D1.V,F(W-D2.W)+D2.V )
变的是:每次的选项都会减少

代码


	@Test
	public void test1(){
		/**
		 *  体积W  :   2   3   4   5
		 *  价值V  :   3   4   5   6
		 */
		Dong [] dongs =new Dong[4];
		dongs[3] = new Dong(2,3);
		dongs[2] = new Dong(3,4);
		dongs[1] = new Dong(4,5);
		dongs[0] = new Dong(5,6);
		// 背包体积
		int w = 8; 
		// 问题:求 钱的张数最小
		Solution Solution = new Solution();
		byte [] seleted = new byte[dongs.length];
		Assert.assertEquals(10, Solution.maxValue01(dongs,w,seleted));
	}

	class Solution {
		public int maxValue01(Dong[] dongs,int w,byte [] seleted) {
			
			if(w <= 0){
				return 0;
			}

			int maxValue = 0;
			int tempMaxValue = 0;
			for(int i = 0 ; i < dongs.length ; i++,tempMaxValue = 0){
				// 如果选择了,跳过去
				if(seleted[i] == 1){
					continue;
				}
				
				if(dongs[i].w > w){
					// 背包装不下:当前东西的体积直接比背包大,装个屁直接忽略
					continue;
				}else if(dongs[i].w <= w){
					// 标记已经选择
					seleted[i] = 1;
					/**
					 * 背包装得下:东西体积跟背包体积一样大,或者小于
					 * 剩余体积能装最大的价值 + 当前装的东西的价值
					 * F(W) = Max( F(W-D1.W) + D1.V, F(W-D2.W)+D2.V )
					 */
					tempMaxValue = maxValue01(dongs , w - dongs[i].w,seleted) + dongs[i].v;
				}
				
				// 如果这种币值的钱张数 比较少就记录
				if(tempMaxValue > maxValue){
					maxValue = tempMaxValue;
				}
				
				// 要遍历下一个了自然需要清除
				seleted[i] = 0;
			}

			return maxValue;
		}
	}

	class Dong{
		public int w;
		public int v;
		public Dong(){}
		public Dong(int w,int v){
			this.w = w;
			this.v = v;
		}
	}

end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

闲猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值