背包问题(动态优化)

背包问题主要场景为:有n个物品,每个物品有自身的价值与重量。有一个背包,最大承受重量为w,求背包最大能够获得的价值是多少。很显然获得最大价值有多种方案,即有多重不同的组合,使得背包中的物品价值最大。最直接的方法,是将n个物品做不同的组合,分别求出他们的价值,最后排序找出最大值。但此方法工作量大,且编程不易实现。

从极限的角度出发,若n值为最小值1时,非常好计算,只需比较物品重量与w的大小,若小于w,则物品不能放入包中,最大价值为0。若大于w,则物品能放入包中,最大价值为物品价值。若n取2时,第二个物品只能取放入与不放入两种状态。若不放入,则背包的价值为n取1时的值V1。若放入,则背包的价值为物品二的价值加上背包剩余容量所承受的最大价值,即,因此当n取2时的最大值,应为,因此n为2时的最大价值,转化为n求的值,可以采用同样的分析方法获得,此问题也转化为重量更小的同类问题。因此我们可以列出一个矩阵,横坐标为背包容量,纵坐标为物品数量,矩阵中的点为背包所能达到的最大价值。矩阵中每个点的计算公式为:

例如有5件物品[4,5,6,2,3],他们的价值为[2,4,5,7,8],背包的容量为7。则有如下矩阵:

核心代为如下所示:

public static  List<List<Integer>> getMax(ArrayList<Item> items ,int capcity){
		
		int n = items.size();
		List<List<Integer>> list = new ArrayList<List<Integer>>();
		for(int i = 0 ; i <= n ; i ++){
			
			List<Integer> values = new ArrayList<Integer>();
			for(int j = 0 ; j <= capcity ; j ++ ){
			
				if(i == 0 ){
					values.add(0);   //当物品为0个时,不管背包的容量多大,总价值都为0
				}
				else if(i == 1){     //当物品为1个时,背包的价值要不为0 ,要不为物品价值
					
					Item it = items.get(i -1);
					if(it.getWeight() > j){
						values.add(0);
					}else{
						values.add(it.getValue());
					}
				}
				else{

					Item it = items.get(i-1);
					if(it.getWeight() >j){ 						//当物品的重量大于背包容量时,物品不能放入背包中
						values.add(list.get(i-1).get(j));
					}else{
						int maxValue = it.getValue() + list.get(i-1).get(j - it.getWeight());
						values.add(maxValue > list.get(i - 1).get(j) ? maxValue : list.get(i-1).get(j));//当物品可放入背包中时,最大容量为不加该物品时的价值与加该物品价值中最大的一个
					}
				}
				
			}
			list.add(values);
		}
		
		return list;
	}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值