0-1背包问题动态规划

来源:互联网 发布:极智seo团队 编辑:程序博客网 时间:2024/05/14 19:49

基本的0-1背包问题。这里的物品一般指花瓶、玉器什么的,要么拿,要么不拿,只有0和1两种状态,所以也叫0-1背包。

初学者有时会认为,0-1背包可以这样求解:计算每个物品的这里写图片描述,然后依据这里写图片描述的值,对所有的物品从大到小进行排序。其实这种贪心方法是错误的。如下表,有三件物品,背包的最大负重量是50,求可以取得的最大价值。
这里写图片描述

其实,0-1背包是DP的一个经典实例,可以用动态规划求解。

0-1背包问题:
有N件物品和一个容量为V的背包。第i件物品的重量是w[i],价值是v[i]。求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大。

转移方程如图所示。
这里写图片描述

解释一下上面的方程:将前i件物品放入容量为j的背包中这个问题时,如果只考虑第i件物品放或者不放,那么就可以转化为只涉及前i-1件物品的问题。
1)如果不放第i件物品,则问题转化为前i-1件物品放入容量为j的背包中。

2)如果这里写图片描述,即背包剩余容量可以容纳第i件物品,那么放第i件物品,则问题转化为前i-1件物品放入剩下的容量为这里写图片描述的背包中,此时能获得的最大价值就是这里写图片描述再加上通过放入第i件物品获得的价值这里写图片描述。则这里写图片描述的值就是1)、2)中最大的那个值。

代码如下

public class Demo1 {    //总的重量    int totalWeight ;    //物品个数    int number ;    public Demo1(int number,int totalWeight){        this.totalWeight = totalWeight ;        this.number = number ;    }    public int knapsack(int w[],int v[]){        int m[][] = new int[number+1][totalWeight+1] ;        for(int j=0;j<totalWeight+1 ;j++){            m[0][j] = 0 ;        }        for(int i=0;i<number+1;i++){            m[i][0] = 0 ;        }        for(int i=1;i<number+1;i++){            for(int j=1;j<totalWeight+1;j++){                if(j>=w[i-1]){                    m[i][j] = Math.max(m[i-1][j],m[i-1][j-w[i-1]]+v[i-1]) ;                }else{                    m[i][j] = m[i-1][j] ;                }            }        }        for(int i=0;i<number+1;i++){            for(int j=0;j<totalWeight+1;j++){                System.out.print(m[i][j]+ " " );            }            System.out.println();        }        return m[number][totalWeight] ;    }    public static void main(String args[]){        //重量        int w[] = {3,4,5} ;        //价值        int v[] = {4,5,6} ;        Demo1 demo = new Demo1(3,10) ;        int weight = demo.knapsack(w,v) ;        System.out.println(weight);    }}

背包容量的增长如图所示
这里写图片描述

0 0
原创粉丝点击