揹包問題跟昨天發表的硬幣找零問題很是相似。html
你得到一張免費超市購物券,它不限制你選擇的物品金額,可是限制物品的容量,也就是給你一個指定大小的購物袋。java
如何在指定容量的購物袋(揹包)中挑選價值最高的物品?git
假設超市裏有音響、PC、吉他和iPod,它們的價值和體積以下所示,咱們有一個大小爲3的購物袋。github
那咱們該如何作出最佳選擇呢?post
與以前的硬幣問題 同樣,咱們選擇一個商品時候會面臨選擇這個商品和不選擇這個商品兩種狀況。spa
若是咱們選擇這個商品,那麼當前最高價值就是沒有選擇這個商品的最高價值 + 當前商品的價值,固然咱們須要考慮一個容量的問題code
若是咱們沒有選擇這個商品,那麼當前最高價值就是以前的最高價值。htm
一樣咱們也須要考慮邊界條件。blog
下面是個人推算過程:遞歸
代碼以下:
/** * 功能描述: 假設你有一個重量爲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; }