天天看点

(背包一)0-1背包问题

问题描述

小偷的背包容量是固定的W,物品重量wt[],对应的价值val[]。那么背包最大可以装多大的价值呢?

示例输入:
           
int[] val = {,,,,};
        int[] wt = {,,,,};
        int W =;
           
最大价值目测是48+8+7=63,容量刚好为6+1+1=8.那么对于复杂的输入,该如何写算法呢?
           

动态规划思路

二维数组dp[][], 行表示物体重量wt,列从底至顶0,1,2...W.

决策:放不放第i个物体呢?不放,则为i-1时的价值;放,则为i-1个物体在剩余容量下的价值+当前物体价值

公式:

(1) v[i][0]=v[0][j]=0;
(2) v[i][j]=Math.max(v[i-1][j],v[i-1][j-wt[i]]+val[i]); //(wt[i]<=j)
(3) v[i][j]=v[i-1][j]; //(wt[i]>j)
           

step1:初始化

weight \ capacity 1 2 3 4 5 6 7 8
[0]->0 –0– –0– –0– –0– –0– –0– –0– –0– –0–
[1]->6 –0–
[2]->5 –0–
[3]->2 –0–
[4]->1 –0–
[5]->1 –0–

step1:从上到下从左到右依次填表

weight \ capacity 1 2 3 4 5 6 7 8
[0]->0 –0– –0– –0– –0– –0– –0– –0– –0– –0–
[1]->6 –0– >
[2]->5 –0–
[3]->2 –0–
[4]->1 –0– V[raw][col]
[5]->1 –0–

代码

public class BeiBao01 {
    public static void main(String[] args) {

        //先定义出背包的一些数属性

        int[] val = {,,,,};
        int[] wt = {,,,,};
        int W =;
        //int[] val = {10,40,30,50};
        //int[] wt = {5,4,6,3};
        //int W =12;

        int result = backpackage(val, wt, W);
        System.out.println(result);     
    }

    public static int backpackage(int[] val, int[] wt, int W){
        //1.获得物品(或价值)总数目
        int N = val.length;
        //2.建一个矩阵,行和列都多一行。0行0列都填充0
        /*     w
         *     0 1 2 3 4 5 6 7 8
         *n 0    
         *  1    * * * * * * * *
         *  2    *
         *  3    *
         *  4    *
         *  5    *
         */
        int[][] V = new int[N+][W+];
        //3.将0行0列都值为零
        for(int columns=;columns<=W;columns++){
            V[][columns]=;
        }
        for(int row=;row<=N;row++){
            V[row][]=;
        }
        //4.一行一行的填充,遍历二维数组即可

        for(int row = ;row<=N;row++){
            for(int columns=;columns<=W;columns++){
                //5.算法的精髓:矩阵怎么填充呢?
                //  V[i][j]=V[i-1][j]或者是V[i-1][j-当前重量]+当前价值   中的较大的那个
                if(wt[row-]<=columns){    //单个重量比总容量小时。由于后边要做减法,做个判断(注意:等号不能忘)
                    V[row][columns]=Math.max(V[row-][columns], 
                            V[row-][columns-wt[row-]]+val[row-]);
                }else{
                    V[row][columns]=V[row-][columns];
                }
            }
        }
        //6.选出最大值       
        //Printing the matrix
        /*
        for (int[] rows : V) {
            for (int col : rows) {
                System.out.format("%5d", col);
            }
            System.out.println();
        }        
        */
        int i=N;
        int j=W;
        while(i>&&j>){
            if(V[i][j]>V[i-][j]){
                System.out.println("第"+i+"件物品,重"+wt[i-]+",价值"+val[i-]+"放入");
                j=j-wt[i-];
                i--;
            }else{
                i--;
            }
        }


        return V[N][W];
    }
}

//结果
第件物品,重,价值放入
第件物品,重,价值放入
第件物品,重,价值放入