代码随想录动态规划——完全背包理论

题目

有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品都有无限个(也就是可以放入背包多次),求解将哪些物品装入背包里物品价值总和最大。

完全背包和01背包问题唯一不同的地方就是,每种物品有无限件。

例子:
背包最大重量为4。
物品为:
在这里插入图片描述
每件商品都有无限个!问背包能背的物品最大价值是多少?

思路

01背包和完全背包的唯一不同就是体现在遍历顺序上

以下是01背包的核心代码:

for(int i = 0; i < weight.length; i++){// 遍历物品
	for(int j = bagsize; j >= weight[i]; j--){// 反向遍历背包容量
		dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
	}
}

其中01背包内部循环从大到小遍历,为了保证每个物品被添加一次
完全背包的物品是可以添加多次的,所以要从小到大去遍历

for(int i = 0; i < weight.length; i++){//遍历物品
	for(int j = weight[i] ; j <= bagsize; j++){// 正向遍历背包容量
		dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
	}
}

另外需要注意的是,在01背包中,二维dp数组的两个for循环遍历先后顺序可以颠倒,但是01背包的一维dp数组的两个for循环一定是先遍历物品,再遍历背包容量

而在完全背包中,对于一维dp数组来说,两个for循环顺序无所谓,都不影响计算dp[j]所需要的值(这个值就是下标j之前所对应的dp[j]

这里只针对纯完全背包问题(两个for循环先后顺序可以颠倒),但是如果题目有变化,就会体现在遍历顺序上了

java代码如下:

//先遍历物品,再遍历背包
public static void testCompletePack(){
	int[] weight = {1,3,4};
	int[] value = {15,20,30};
	int bagsize = 4;
	int[] dp new int[bagsize+1];
	for(int i = 0; i < weight.length; i++){//遍历物品
		for(int j = weight[i]; j <= bagsize; j++){//正序遍历(因为一个物品可以重复添加多次),遍历背包容量
			dp[j] = Math.max(dp[j], dp[j - weight[i]] + values[i]);
		}
	}
	for(int maxValue : dp){
		System.out.println(maxValue + "   ");
	}
}
//先遍历背包,再遍历物品
public static void testCompletePack1(){
	int[] weight = {1,3,4};
	int[] value = {15,20,30};
	int bagsize = 4;
	int[] dp new int[bagsize+1];
	for(int i = 1; i <= bagsize; i++){//遍历背包容量
		for(int j = 0; j < weight.length ; j++){//正序遍历物品
			if( i - weight[j] >= 0){
				dp[i] = Math.max(dp[i], dp[i - weight[j]] + value[j]);
			}
		}
	}
	for(int maxValue : dp){
		System.out.println(maxValue + "   ");
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

HDU-五七小卡

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

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

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

打赏作者

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

抵扣说明:

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

余额充值