問題描述:
現有n件物品和乙個容量為c的揹包。第i件物品的重量是重量為w[i],價值是v[i]。已知對於一件物品必須選擇取(用1表示)或者不取(用0表示),且每件物品只能被取一次(這就是「0-1」的含義)。求放置哪些物品進揹包,可使這些物品的重量總和不超過揹包容量,且價值總和最大。
求解思路:(1)將第二件物品放入揹包,那麼揹包中物品的最大價值是多少呢?因為第二件物品重量為w[1]=2,在將第二件物品放入揹包之前,揹包的容量應為j-w[1]=8-2=6,此時揹包的最大價值是m[0][6],因此若將第二件物品放入揹包,其揹包的最大價值m[1][j]=m[0][j-w[1]]+v[1];
(2)不將第二件物品放入揹包,那麼此時揹包中物品的最大價值依然為只放入第一件物品時揹包的最大價值,即m[1][j]=m[0][j];
我們選取(1)(2)中價值的較大者作為i=1,j=8時揹包中的最大價值。
i=2,3,4時的分析同上,直到揹包的容量為10,此時m[4][10]即為揹包中物品的最大價值。
有了上面的分析,我們很容易寫出下面的遞迴關係:
(1)i=0 當j < w[0]時,m[0][j]=0;當j>=w[0]時,m[0][j]=v[0]。
(2)i>0 當j < w[i],m[i][j]=m[i-1][j];當j>=w[i],m[i][j]=max。
得到了滿足約束條件的揹包中物品的最大價值後,需要知道是哪些物品被放入了揹包。觀察二維表m[i][j],我們注意到m[i][c]表示當揹包重量為題目中要求的c時揹包的最大價值,那麼在得到m[i][c]之前,我們必然是比較了m[i-1][j-w[i]]+v[i]與m[i-1][j]的大小,從而決定是否將物品放入揹包。所以我們可以利用回溯的方法,若m[i][j]=m[i-1][j],那麼物品沒有放入揹包;否則物品一定被放入揹包。因此我們可以從最後一件物品開始,一步一步回退到第一件物品,直到找到所有的物品放入揹包的情況。本題中物品的裝入情況如表中紅色和藍色部分所示,其中紅色表示當前物品被裝入揹包,藍色表示沒有裝入揹包。
package com.ibm.cfs.asset.management.api.ms.property;
public
class main ; //每個物品重量
int v = ; //每個物品價值
int c = 10; //揹包容量
int flag = new
int[5]; //記錄物品裝入情況,0表示不裝入,1表示裝入
flag[0] = 1; //初始值表示第乙個物品已裝入揹包
int table = new
int[n][c + 1];//需要維護的二維表,為了方便計算加入一列,其中第0列表示揹包容量為0時揹包的最大價值為0
/* * 初始化第一行,即揹包中裝入第一件物品
* */
for (int j = 1; j <= c; j++) }/*
* 揹包中依次裝入物品
* */
for (int i = 1; i < n; i++)
else }}
system.out.println("揹包的最大價值為:" + table[n - 1][c]);
//獲取裝入揹包的物品編號 回溯
for (int i = n - 1; i >= 1; i--) else flag[i] = 0; //沒有裝入揹包
}system.out.print("裝入揹包的物品編號是:");
for (int i = 0; i < n; i++)
}}
揹包問題 01揹包問題
n個物品,總體積是v,每個物品的體積的vi,每個物品的最大價值是wi,在不超過v的體積下求最大價值 eg揹包容積為 5 物品數量為 4 物品的體積分別為 物品的價值分別為 思路定義乙個二位陣列int f new int n 1 v 1 f i j 就表示在1 i個物品中選取體積小於v的情況的最大價值...
揹包問題 01揹包
有n件物品和乙個容量為v的揹包。第i件物品的重量是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。01揹包中的 01 就是一種物品只有1件,你可以選擇放進去揹包即1,也可以選擇不放入揹包中即0。include include using namespace std const int ...
揹包問題(01揹包)
1085 揹包問題 在n件物品取出若干件放在容量為w的揹包裡,每件物品的體積為w1,w2 wn wi為整數 與之相對應的價值為p1,p2 pn pi為整數 求揹包能夠容納的最大價值。input 第1行,2個整數,n和w中間用空格隔開。n為物品的數量,w為揹包的容量。1 n 100,1 w 10000...