套路---动态规划----解决背包问题

经典动态规划问题

给你⼀个可装载重量为W	的背包和	N	个物品,每个物品有重量和价值两 个属性。其中第i	个物品的重量为wt[i],价值为	val[i]	,现在让你⽤ 这个背包装物品,最多能装的价值是多少?
1.明确背包问题的实质:
1)第一个想法是使用贪婪法,每次取价值最高的那个,但是这种办法并不一定能够得到最优,例如10kg的背包 有8kg价值9元的物品1,3kg 价值3元的物品2,和8kg价值7元的物品3;
如果选择物品1 背包无法装其他的物品 价值为9;
		 但是 选择物品2和物品3 价值为10;
2)因为对于物品来说是个整体,要么不装 要么装,当背包无法装入物品时,无法获得这个物品的价值,所以要获得更大的价值,最简单的办法就是枚举所有的可能。
3)动态规划的本质就是枚举,只是通过已经计算出来的结果减少计算量,相当于通过建立一个备忘录,利用空间换时间。

动态规划的套路

1.建立动态规划数组,并明确其含义;
dp[i][j]
i:代表选择第i个物品
j:代表当前背包的重量
dp[i][j]:代表当前背包中物品的价值
2.赋予初值
i=0 即无物品选择时 dp[0][j]=0;
3.状态和选择
背包的状态即 i, j
对于i来说 第i个物品选择放入背包和不放背包 两种状态
根据i的状态 j = (j - w) + w(装入此物品,要腾出 w 的空间,腾出之前的价值根据已经计算的价值获得,若j-w<0,则无法装入,选择不放。

1)不放: dp[i][j]=dp[i-1][j];
2) 放 :dp[i][j]=dp[i-1][j-w]+v;
(dp[i-1][j-w] 代表不放这个物品 只有j-w空间时的最大价值,v 代表当前物品价值)

背包问题的dp[],容量为20
代码:

import java.util.*
Class Solution{
public packetProblem(int[] w, int[] v, int total){
	int m = w.length; //物品数量
	int[][] dp = new int[m + 1][total + 1]; //建立dp table
	//dp[0][j]==0  物品 i 从 1 开始
	for(int i = 1; i <= m; i++){
		for(int j = 0; j <= total; j++){
			//作选择
			//1.如果空间不足 不选该i物品
			if(j - w[i - 1] < 0)
			dp[i][j] = dp[i - 1][j];
			//2.空间足够
			else {
			//比较选择和不选择i物品价值 决定dp[i][j]
			dp[i][j] = Math.max(dp[i - 1][j - w[i - 1]] + v[i - 1], dp[i - 1][j]);
			}
		} 
	}
	//答案是选择到m件商品 容量为total时
	return dp[m][total];
}
}

推荐一个背包问题dp table 的网站
https://misakasister.github.io/Online_0-1_Knapsack/index.html
一目了然

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值