01揹包問題描述:給定n個體積為v1....vn,價值為p1...pn的物品和乙個體積為v的包,求能夠裝進包中物品的最大價值。
為了設計乙個動態規劃演算法,我們需要匯出狀態轉移方程。先考慮原問題的子問題,假設我們考慮前i個問題,揹包容積為j,記將前i個物品裝到容積為j的包中最大總價值為w[i,j];每個物品只有選擇和不選擇兩種情況,我們根據第i個物品是否選擇進行分類。在不包含第i個物品的最優解價值為w[i-1,j],在包含第i個物品的最優解中,最優子集是該物品和前i-1個物品中能夠放入最大體積 j - v[i](j-v[i]>0)的揹包的最優解組成。這時候最優解為p[i]+w[i-1,j-v[i]];於是在前i個物品的最優解是這兩種情況的最大值。特殊情況,第i個物品本身體積大於包時,從前i個物品中選出的最優解價值等於從前i-1個物品中選出的最優解的價值。
狀態轉移方程:w[i,j]=max(j-v[i]>=0),若j-v[i]<0,則w[i,j]=w[i-1,j].
上面狀態轉移方程時間和空間複雜度均為o(vn),時間複雜度無法優化,而空間複雜度還可以繼續優化。我們可以使用一維陣列來代替上面的二維陣列,則狀態轉移方程如下:
w[ j ]=max (j>=v[ i ])
其中左邊的w[j]是w[i,j],右邊的w[j]是w[i-1,j],w[j-v[i]]是w[i-1][j-v[i]].可以用下面迴圈:
for(i=1;i<=n;i++)
for(j=v;j>=v[i];j--)
......
這樣一來空間複雜度為o(v);我們再來看初始化的問題,揹包問題有兩種情況。第一種要求揹包裝滿,在初始化時w[0]=0,而w[1..v]= -1,因為在0個物品情況下,只有體積為0的揹包可以看做什麼也不放入即是他的合法解,而包體積j>0時是無論如何也裝不滿的,於是找不到合法的解,標誌為-1;第二種是不要求揹包裝滿的情況,則可以將w[0...v]=0全部初始化為0,這時有0個物品,包裡什麼也不裝就是它的合法解,總價值都為0;下面兩種情況c++**:
#includeusing namespace std;#define max_size 500
int n, v;
int w[max_size];
int p[max_size];
int v[max_size];
int main()
} cout << w[v] << endl;
return 0;
}
#includeusing namespace std;
#define max_size 500
int n, v;
int w[max_size];
int p[max_size];
int v[max_size];
int bag01(int v, int p);
int main(){
int i,j,pos;
memset(w,0, sizeof(w)); //邊界初始化
cin >> n >>v;
for (i = 1; i <= n; i++)
cin >> v[i] >> p[i];
for (i = 1; i <= n; i++){
for (j = v; j >= v[i]; j--){
pos = j - v[i];
if ( w[j]
揹包問題 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...