揹包問題主要包含以下3種基本的問題:
其中對於每一種xx揹包問題還存在乙個特殊的情形,即要求揹包恰好被裝滿,這種特殊問題的求解主要是在動態規劃的狀態陣列的初始化做一下特殊的處理。
除此之外,有時候我們不僅僅要求揹包能裝下的最大物品的價值,我們還希望得到具體的裝包方案,這裡就會涉及到狀態陣列的回溯(track),下面會舉例說明。
01揹包問題是揹包問題中最簡單最基礎的一類問題,問題描述如下:給定n
n
件物品,對於第
i' role="presentation">i
i件物品,其價值為vi
v
i,重量為wi
w
i,與此同時還存在乙個體積為
v v
的揹包,每件物品只有一件,因此每件物品可以選擇是否放進揹包,求揹包能裝下的物品的最大價值
p' role="presentation">pp。
對於該問題,對應的數學模型是乙個簡單的01規劃問題:
對應的模型為:s.
t.∑n
i=1w
i∗xi
<=v,
xi=0
,1s .t
.∑i=
1nwi
∗xi<=v,
xi=0
,1maxp=∑
ni=1
vi∗x
i max
p=∑i
=1nv
i∗xi
01揹包問題常常採用動態規劃的方法去求解,狀態轉移方程為:
else }}
return dp[value.length - 1][bagv];
}上述**裡面的兩層for迴圈,由於是從1開始的,因此對於對於引數value
,裡面的有效資料應該也是從1開始計數的,因此在value
陣列和weight
陣列的第乙個元素都應該置為0。
public
static
void
main(string args) ;// 物品的價值
int weight = new
int ;// 物品的重量
int bagv = 15;// 揹包的大小
system.out.println(knapsackproblemzeroone(value, weight, bagv));
}
實現細節:
dp陣列的求解正如如下**一樣,從左上到右下依次求解:
上述演算法的時間複雜度為o(
nv) o(n
v),其中n n
為物品的數量,
v' role="presentation">v
v為揹包的體積。
但是通過上述的狀態轉移方程我們發現,其實fi
,jf i,
j的值僅僅和fi
−1,j
f i−
1,j, fi
−1,j
−wi fi−
1,j−
wi有關,也就是說第
i i
件物品只和前一件物品有關(dp二維陣列的第i行可以通過第i-1行推出來),因此我們可以將二維陣列改寫為一維陣列,俗稱滾動陣列。
public
static
intknapsackproblemzerooneoptimization(int value, int weight, int bagv)
}return dp[bagv];
}
關鍵要理解這裡的寫法:
for (int j = bagv; j >= weight[i]; j--)
經過此番優化後,時間複雜度不變,空間複雜度降為o(
v)' role="presentation">o(v
)o(v
)。以上的演算法只是給出能夠得到的最大收益值
p p
,但是有時候我們希望得到具體的裝包方案,即我們需要知道哪些物品需要裝包,哪些不需要。
根據狀態陣列從後往前倒退,即可得到一條路徑,將該路徑上的資訊儲存便可以得到方案。
對於dp[i][j],該值**於兩個地方:
因此可以寫出下面的**求得裝包方案:
public
static
int tracback(int dp, int weight, int bagv) else
}res[0] = dp[0][j] > 0 ? 1 : 0;
return res;
}
狀態回溯的求解正如如下二維**一樣,從右下往左上倒推:
揹包問題 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...