背包问题

令Vi、Wi 分别表示第i个物品的价值和体积,V(i,j)表示前i个物品能装入背包容量为j的背包的最大价值,有以下动态规划函数:

当背包容量j小于当前物品的重量wi时,物品i肯定不能放到背包里,则当前最优解为V(i-1,j);

当背包容量j大于当前物品的重量wii时,物品i可以放到背包里,但是到底放不放呢?那就要看不放入物品i(最大价值是V(i-1,j))和放入物品j(最大价值是V(i-1,j-wi)+vi)那个更大。

其中V(i-1,j)和V(i-1,j-wi)的最优值可以通过查找之前计算并记录的表得到。

详细步骤如下:

第-1行中从左往右表示背包重量一次增加1,第-1列从上往下一次表示考虑前i个物品。

初始情况一:对于第0列,它的含义是背包的容量为0。此时物品的价值呢?没有。因此,第一列都填入0。

初始情况二:对于第0行,它的含义是屋内没有物品。那么没有任何物品的背包里的价值多少呢?还是没有!所有都是0。

复杂度

解法的复杂度非常直观。在N次循环中有W次循环 => O(NW)

实现

Java代码实现:

class Knapsack {
    public static void main(String[] args) throws Exception {
        int val[] = {10, 40, 30, 50};
        int wt[] = {5, 4, 6, 3};
        int W = 10;
 
        System.out.println(knapsack(val, wt, W));
    }
 
    public static int knapsack(int val[], int wt[], int W) {
        //Get the total number of items. 
        //Could be wt.length or val.length. Doesn't matter
        int N = wt.length; 
 
        //Create a matrix. 
        //Items are in rows and weight at in columns +1 on each side
        int[][] V = new int[N + 1][W + 1]; 
 
        //What if the knapsack's capacity is 0 - Set
        //all columns at row 0 to be 0
        for (int col = 0; col <= W; col++) {
            V[0][col] = 0;
        }
 
        //What if there are no items at home.  
        //Fill the first row with 0
        for (int row = 0; row <= N; row++) {
            V[row][0] = 0;
        }
 
        for (int item=1;item<=N;item++){
            //Let's fill the values row by row
            for (int weight=1;weight<=W;weight++){
                //Is the current items weight less
                //than or equal to running weight
                if (wt[item-1]<=weight){
                    //Given a weight, check if the value of the current 
                    //item + value of the item that we could afford 
                    //with the remaining weight is greater than the value
                    //without the current item itself
                    V[item][weight]=Math.max (val[item-1]+V[item-1][weight-wt[item-1]], V[item-1][weight]);
                }
                else {
                    //If the current item's weight is more than the
                    //running weight, just carry forward the value
                    //without the current item
                    V[item][weight]=V[item-1][weight];
                }
            }
 
        }
 
        //Printing the matrix
        for (int[] rows : V) {
            for (int col : rows) {
                System.out.format("%5d", col);
            }
            System.out.println();
        }
 
        return V[N][W];
    }
}

原文链接: javacodegeeks 翻译: ImportNew.com hejiani
译文链接: http://www.importnew.com/13072.html
转载请保留原文出处、译者和译文链接。]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值