java——动态规划03

01背包问题:

背包问题算是动态规划中,最经典的题目了,分为01背包,和完全背包问题,不过两者有比较密切的关系,01背包搞明白了,完全背包自然迎刃而解,下面和大家共同探索一道01背包最大价值问题。

题目描述:

有一下商品,价值和重量如表所示,问给定一个重量为4的背包,怎样装东西,能使获得的价值最大。

商品价值重量
手机15001
吹风机8002
平板20002

解决此问题时,最好借用画表的方法,由于本人也是刚开始学,所以把想法说明下。

咱们先建立一个二维数组dp[i][j],w[i]表示第i件商品的重量,背包重量W,用来表示前i件商品中获得的最大价值。

刚开始一件商品也不选,则背包内价值为0,也就是二维数组的第一行全0(dp[0][j]),同样的假设背包重量为0,则一件商品也装不进去,所以第一列全为0(dp[i][0]),初始化第一行和第一列后,开始依次往背包放东西。

第一次只允许第一件商品放入,则在第一行所有重量满足的情况下,都将获得第一件商品的价值。

接下来允许放入两件商品,同理在重量满足的情况下,需考虑是否将第二件商品放入背包,这就需要比较,前i件商品的价值,与加上背包的价值,哪个价值更大。由此可以有以下代码:

public class test12 {
	public static void main(String[] args) {
		int[]w={1,2,2};//物品的重量
		int[]val={1500,800,2000};//物品的价值
		int m=4;//背包的重量
		int n=val.length;
		int[][]v=new int[n+1][m+1];//二维数组,用来表示前i件商品的最大价值
		int[][]path=new int[n+1][m+1];//用来记录哪个商品被放入背包
		for(int i=1;i<v.length;i++){//这里从i=1,j=1开始遍历,和商品对应
			for(int j=1;j<v[0].length;j++){
				if(w[i-1]>j){//当商品重量大于背包重量
					v[i][j]=v[i-1][j];
				}
				else{//当背包重量大于商品重量时
					if(v[i-1][j]<val[i-1]+v[i-1][j-w[i-1]]){//判断在剩下的重量 选择放还是不放,要比较价值的大小,不放时和放时
						v[i][j]=val[i-1]+v[i-1][j-w[i-1]];
						path[i][j]=1;//选择了放,将放入的进行标记
					}
					else{//没有放进去
						v[i][j]=v[i-1][j];
					}
				}
			}
		}
		System.out.println(v[n][m]);//打印最大价值

		for(int i=0;i<v.length;i++){//输出价值表
			for(int j=0;j<v[0].length;j++){
				System.out.print(v[i][j]+" ");
			}
			System.out.println();
		}
		System.out.println("--------------------");
		int s=path.length-1;
		int q=path[0].length-1;
		while(s>0&&q>0){//判断输出选择的商品,这里从后往前遍历,否则有冗余情况
			if(path[s][q]==1){
				System.out.println("把第"+s+"个装入背包内");
				q-=w[s-1];//将最后放进去后,重量将发生变化,求剩余重量
			}
			s--;//下一个商品
		}
	}
}

结果如下:

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值