01背包动态规划

1.动态规划  
  什么是动态规划?动态规划就是将一个大问题不断向下拆分成小问题,直到拆分出的小问题可以求出其解,然后将小问题的解不断的向上合并,最终得到大问题的解决方案。

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

3.算法分析
  假设前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] }。  


  上表从上往下,由左至右依次遍历。假设F3的背包承重为3,此时物品的重量为4,所以该物品无法放入背包中,此时背包可以获得的最大总价值为E3的最大总价值25。假设E10的背包承重为10,此时物品的重量为4,所以该物品可以放入背包中,当该物品不放入背包中时,背包的价值为D10的最大价值62,放入背包中时背包的价值为D6的最大价值加上该物品的价值,结果为77,因此最终得出E10的最大价值为77。 
  创建物品对象,存在重量和价值两种属性。


public class Thing {
	private int weight;
	private int value;
	public Thing(int weight,int value) {
		// TODO Auto-generated constructor stub
		this.weight=weight;
		this.value=value;
	}
	@Override
	public String toString() {
		return "Thing [weight=" + weight + ", value=" + value + "]";
	}
	public int getWeight() {
		return weight;
	}
	public void setWeight(int weight) {
		this.weight = weight;
	}
	public int getValue() {
		return value;
	}
	public void setValue(int value) {
		this.value = value;
	}
	
}

public class BeiBao {
	private Thing[] things;
	private int n;//商品数量
	private int totalWeight;//背包总承重
	private int[][] bestValue;//一维:商品数量,二维:背包总承重,值:商品价值
	
	public BeiBao(Thing[] things,int totalWeight) {
		// TODO Auto-generated constructor stub
		this.things=things;
		this.n=things.length;
		this.totalWeight=totalWeight;
		bestValue=new int[n+1][totalWeight+1];
	}
	
	public int zeroOneBeiBao(){
		//遍历背包的重量
		for(int j=0;j<=totalWeight;j++){
			for(int i=0;i<=n;i++){
				if(j==0||i==0){
					bestValue[i][j]=0;
				}else{
					if(j<things[i-1].getWeight()){//如果背包放不下当前商品 ,注意这里是thing[i-1]					bestValue[i][j]=bestValue[i-1][j];
					}else{//背包放的下商品
						int weight=things[i-1].getWeight();
						int value=things[i-1].getValue();
						//那么最大价值就在  放下商品的背包  和  不放下商品的背包中  取较大值
						bestValue[i][j]=Math.max(bestValue[i-1][j-weight]+value, bestValue[i-1][j]);
					}
					
				}
			}
			
		}
		return bestValue[n][totalWeight];
		
	}
	
	public static void main(String[] args) {
	    Thing[] bags = new Thing[] { new Thing(2, 13),
	            new Thing(1, 10), new Thing(3, 24), new Thing(2, 15),
	            new Thing(4, 28), new Thing(5, 33), new Thing(3, 20),
	            new Thing(1, 8) };
	    int totalWeight = 12;
	    BeiBao problem = new BeiBao(bags,totalWeight);

	    int maxValue = problem.zeroOneBeiBao();
	    System.out.println(maxValue);
	}
	
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值