动态规划 - 01背包问题(Java实现)

【问题描述】

         一个旅行者有一个最多能装m公斤的背包,现在有n中物品,每件的重量分别是W1、W2、……、Wn,每件物品的价值分别为C1、C2、……、Cn, 需要将物品放入背包中,要怎么样放才能保证背包中物品的总价值最大?

【思路】

       假设前n个物品,总承重为j,物品的重量为w,其最大价值为v[n,j]。
  在背包的总承重不变的前提下,一个物品是否放入背包中直接影响到后面的物品是否能放入到背包中,即一个物品很重同事物品价值又很低时,若装入背包中直接导致其他更多的物品无法放入背包中,从而使得背包中的最大总价值变低。
  当背包的承重为0,或者不将物品放入背包时,背包中的最大总价值均为0,即v[n,0]=v[0,n]=0。
  放入当前物品n超过背包的最大承重时,则无法将该物品放入背包中,即v[n,j]=v[n-1,j]。 
  放入当前物品n不超过背包的最大承重时,则当前物品放入背包时的最大价值为vn+v[n-1,j-wn],不放入背包时的最大价值为v[n-1,j],因此对于当前物品是否放入背包中所能获得的最大价值v[n,j]=max{ v[n-1,j],vn+v[n-1,j-wn] }

状态转化方程为:

【代码实现】

      /**
	 * @param m : 表示背包的最大容量
	 * @param n : 表示商品的个数
	 * @param w : 表示商品重量数组
	 * @param p : 表示商品价值数组
	 * 
	 */
	public static int[][] DP_01bag(int m,int n,int w[],int p[]){
		//c[i][m] 表示前i件物品恰好放入重量为m的背包时的最大价值
		int c[][] = new int[n+1][m+1];
		
		for(int i=0;i<n+1;i++){
			c[i][0] = 0;
		}
		for(int j=0;j<m+1;j++){
			c[0][j] = 0;
		}
		for(int i=1;i<n+1;i++){
			for(int j=1;j<m+1;j++){
     //当物品为i件重量为j时,如果第i件的重量(w[i-1])小于重量j时,c[i][j]为下列两种情况之一:
     //(1)物品i不放入背包中,所以c[i][j]为c[i-1][j]的值
     //(2)物品i放入背包中,则背包剩余重量为j-w[i-1],所以c[i][j]为c[i-1][j-w[i-1]]的值加上当前物品i的价值	
				if(w[i-1] <= j){
					if(c[i-1][j] <c[i-1][j-w[i-1]]+p[i-1]){
						c[i][j] = c[i-1][j-w[i-1]]+p[i-1];
					}else{
						c[i][j] = c[i-1][j];
					}
					
				}else{
					c[i][j] = c[i-1][j];
				}
			}
		}
		return c;
		
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Wimb

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

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

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

打赏作者

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

抵扣说明:

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

余额充值