揹包問題是乙個np問題:
一般題意為:
存在n件物品,每件物品的重量為w[i],價值為v[i],現在有乙個包,承重限制為weight,現在讓你從n件物品中,選擇一些物品裝入揹包中,在不超重的前提下,使得揹包中所裝物品的總價值最大。
由於每件物品【應該是每種物品】存在著兩種情況,一種是,每種物品唯有一件,這種情況稱為0-1揹包問題;
另一種是,每種物品有無數件,這種情況稱為完全揹包問題。
0-1揹包問題存在兩種情況,即,對於第i種物品,你只有選擇或者不選擇兩種情況。
(1)使用動態規劃來解答:
考慮對第i件物品的選擇策略,有兩種策略:
①不放第i件物品,那麼問題轉化為前i-1件物品恰好裝入容量為weight的揹包中所能獲得的最大價值,也即dp[i-1][weight]。【也就是整個揹包重量用來裝前i-1件物品】
②放第i件物品,那麼問題轉化為前i-1件物品恰好裝入容量為weight-w[i]的揹包中所能獲得的最大價值,也即dp[i-1][weight-w[i]]+c[i]。【也就是前i-1件物品只能裝到重量的v-w[i]】
即選擇物品和不選擇物品這兩種情況而已【weight為當前剩餘的揹包體積】
狀態轉移方程:
核心**為:
for(int i=1; i當然,為了縮小空間複雜度,我們也可以用一維陣列求解,不過,u的遍歷就要逆序遍歷了
狀態轉移方程:
for(int i=0; i<=n; ++i)
for(int u=weight; u>=w[i]; --u)//逆序列舉
dp[i][u] = max(dp[u], dp[u-w[i]]+v[i]);
(2)使用dfs來求解:
很簡單,即分兩條路進行遞迴
void dfs(int index, int sumw, int sumv)
; 1<=i<=n, w[i]<=u<=weight" class="mathcode" src=""/>
邊界:for(int i=1; i一維陣列:
狀態轉移方程:
邊界:for(int i=1; i<=n; ++i)
for(int u=weight; u>=w[i]; --u)
dp[u] = max(dp[u], dp[u-w[i]]+v[i])
使用dfs求解
void dfs(int index, int sumv, int sumw)
}
揹包問題 01揹包總結
寫這篇部落格的原因是因為自己初學揹包的時候覺得好玄學。只是知道怎麼寫,但是具體是為什麼覺得很玄妙。在此其實希望和我一樣的小白萌新早點明白其中的原理,其實原理很簡單,只要懂了這個圖,我想01揹包就不成問題了。首先要明確這張表是至底向上,從左到右生成的。關於01揹包的題目暫時整理了一點。1.簡單01揹包...
揹包問題總結
標籤 acm dp 揹包 n 物品,乙個揹包,每個物品價值wi 體積vi 揹包容量 c 求最大價值 對於物品 i可選可不選 fi j fi 1 j vi j 0 fi j max c j vi 給定 n 種物品和乙個揹包。第 i種物品的價值是 wi 其體積為vi 揹包的容量為 c 同一種物品的數量無...
揹包問題總結
揹包問題主要是分為三種 0 1揹包,完全揹包,多重揹包 1 0 1揹包 定義 何謂0 1揹包,可以這樣想,那裡有一堆值錢的東西,每一樣東西只有一件,他們的價值和體積都不一樣,現在要你從這n件裡面挑選一些放到乙個容量一定的揹包裡面,使得你的揹包裡的東西總價值最大。對於這些東西的每一件,你可以選擇放進你...