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

目录

前言

01背包问题

现实应用

穷举画图

代码


前言

该问题是“最少钱币数问题”的延伸,整个代码结构类似,如果不了解可先参考:

算法.动态规划.最少钱币数问题(Java,递归)_要钱也要自我实现-CSDN博客算法.动态规划.最少钱币数问题(Java,递归)https://blog.csdn.net/weixin_42754896/article/details/123066509

完全背包问题

在N件物品取出若干件放在容量为W的背包里,每种物品的体积为W1,W2……Wn(Wi为整数),与之相对应的价值为P1,P2……Pn(Pi为整数)。求背包能够容纳的最大价值。

跟01背包的区别:每种东西有无限个

现实应用

盗墓者 拿了一个背包,体积W一定。墓葬中有不同体积的金块,价值各不一样。盗墓者当然希望尽可能拿走最大价值的金子。
东西编号 :   D1  D2  D3  D4
体积W  :   2   3   4   5
价值V  :   3   4   5   6
背包体积W:8

穷举画图

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


F(8): 装满体积8的最大价值
D1.W: D1东西的体积
D2.V: D2东西的价值
F(W) = Max( F(W-D1.W) + D1.V,F(W-D2.W)+D2.V )

代码

public class package01 {
	@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();
		Assert.assertEquals(12, Solution.maxValue01(dongs,w));
	}

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

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

			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、付费专栏及课程。

余额充值