揹包問題

揹包問題跟昨天發表的硬幣找零問題很是相似。html

你得到一張免費超市購物券,它不限制你選擇的物品金額,可是限制物品的容量,也就是給你一個指定大小的購物袋。java

如何在指定容量的購物袋(揹包)中挑選價值最高的物品?git

 

 假設超市裏有音響、PC、吉他和iPod,它們的價值和體積以下所示,咱們有一個大小爲3的購物袋。github

那咱們該如何作出最佳選擇呢?post

與以前的硬幣問題 同樣,咱們選擇一個商品時候會面臨選擇這個商品和不選擇這個商品兩種狀況。spa

若是咱們選擇這個商品,那麼當前最高價值就是沒有選擇這個商品的最高價值 + 當前商品的價值,固然咱們須要考慮一個容量的問題code

若是咱們沒有選擇這個商品,那麼當前最高價值就是以前的最高價值。htm

 

 一樣咱們也須要考慮邊界條件。blog

  1. 若是沒有商品,那麼最高價值永遠是0
  2. 若是揹包容量爲0,那麼最高價值也永遠也是0
  3. 若是當前選擇的商品體積大於揹包剩餘的容量,這個商品不該該放進揹包中。

 

下面是個人推算過程:遞歸

代碼以下:

 /**
     * 功能描述: 假設你有一個重量爲packWeight的揹包,商場有的商品爲goods,
     * 你須要挑選一些商品使得揹包中裝的東西的價值最高
     * 假設不能夠重複選擇商品
     * @author lkb
     * @date 2019/6/3
     * @param goods 商品的信息
     * @param packWeight 揹包重量
     * @return java.util.List<com.lkb.dp.problems.pack.Goods>
     */
    public static int packDP(Goods[] goods, int packWeight){
        int[][] value = new int[goods.length + 1][packWeight + 1];

        //揹包的容量爲0
        for(int i=0;i<goods.length + 1;i++){
            value[i][0] = 0;
        }
        //沒有商品
        for(int i=0;i<packWeight+1;i++){
            value[0][i] = 0;
        }

        for(int weight=1; weight<packWeight+1; weight++){
            for(int good=1; good<goods.length + 1; good++){
                //商品的重量大於揹包的容量
                if(goods[good-1].getWeight() > weight){
                    value[good][weight] = value[good-1][weight];
                    continue;
                }
                if(weight - goods[good-1].getWeight() >= 0){
                    if((value[good][weight - goods[good-1].getWeight()] + goods[good-1].getValue()) > value[good-1][weight] ){
                        //選擇當前物品的價值大於不選擇當前物品的價值
                        value[good][weight] = value[good][weight - goods[good-1].getWeight()] + goods[good-1].getValue();
                    }else{
                        //選擇當前物品的價值小於不選擇當前物品的價值
                        value[good][weight] =  value[good-1][weight];
                    }
                }
            }
        }
        return value[goods.length][packWeight];
    }

 

下面是簡單遞歸的實現方式。

    /**
     * 功能描述: 假設你有一個重量爲packWeight的揹包,商場有的商品爲goods,
     * 你須要挑選一些商品使得揹包中裝的東西的價值最高
     * 假設不能夠重複選擇商品
     * @author lkb
     * @date 2019/6/3
     * @param goods 商品的信息
     * @param packWeight 揹包重量
     * @return java.util.List<com.lkb.dp.problems.pack.Goods>
     */
    public static int pack(Goods[] goods, int packWeight){
        int maxValue = 0;
        Map<Integer,List<Goods>> map = new HashMap<>();
        for(int i=0;i<goods.length;i++){
            int weight = packWeight - goods[i].getWeight();
            int value = goods[i].getValue();
            for(int j=0;j<goods.length;j++) {
                //只要揹包的容量夠,咱們就應該嘗試選擇這個物品
                //後續再比較最大值
                if (weight - goods[j].getWeight() >= 0) {
                    value = goods[j].getValue() + value;
                    weight = weight - goods[j].getWeight();
                }
            }
            if(maxValue < value){
                maxValue = value;
            }
        }
        return maxValue;
    }

 

 

你們也能夠在這個地址下載源碼,或者關注個人公衆號,一塊兒見證個人成長。

歡迎關注個人公衆號 -- 成長爲大牛
相關文章
相關標籤/搜索