揹包問題在不同的資料中可能分為不同的類別,在學習揹包問題時,我們將揹包分為以下幾類:01揹包,完全揹包,多重揹包,分組揹包。
先乙個乙個說起:
一、01揹包:
有n件物品和乙個容量為v的揹包。第i件物品的費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可使價值總和最大。
這是求最大利潤值的01揹包問題,01揹包是最基礎的揹包問題,其中0,1的由來就是放或不放兩種選擇的問題(物品只有一件,對於每種物品都是兩種選擇。)
根據問題我們便可以建立狀態轉移方程:
f[i][v]=max
其中f[i][v]表示前i件物品恰好放入乙個容量為v的揹包可獲得的最大價值(f[i][v]在第i件物品的選擇上對價值總和而言還與前i-1件物品的價值總和有關,再根據第i件物品是否選擇可列出方程)
優化空間複雜度:
上面的狀態轉移方程為二維陣列,當資料量較大時容易占用大量記憶體空間,如果我們能夠將二維陣列轉化為一維陣列會節省大量空間:我們可以通過規律發現每次第i件物品都只與前i-1件物品有關,所以我們不在寫出i,i-1之間的關係,將它們省略掉,寫成:f[v]=max; 這裡我們仍預設i從1到n的迴圈關係。
對於揹包問題,還有一處細節(要求),就是看揹包是否裝滿:初始化細節:若要求恰好裝滿揹包,初始化時除了f[0]為0其它f[1…v]均設為-∞,-∞表示揹包在此時並未裝滿,並沒有達到要求。若沒有要求必須把揹包裝滿,初始化時將f[0…v]全部設為0
二、完全揹包
有n種物品和乙個容量為v的揹包,每種物品都有無限件可用。第i種物品的費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。
完全揹包與01揹包唯一的區別就是物品充足,可以隨意裝入,當然我們可以轉化為01揹包:考慮到第i種物品最多選v/c[i]件,於是可以把第i種物品轉化為v/c[i]件費用及價值均不變的物品,然後求解這個01揹包問題 。f[i][v]=max;m=v/c[i];即f[v]=max 。
此處v的迴圈次序和01揹包的迴圈次序不同,01揹包是v…0;完全揹包是0…v。
三、多重揹包:
有n種物品和乙個容量為v的揹包。第i種物品最多有n[i]件可用,每件費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大 。
相對於完全揹包物品的數量進行了限制,基本的方程只需將完全揹包問題的方程略微一改即可,因為對於第 i 種物品有 n[i]+1 種策略:取 0 件,取 1 件… 取 n[i] 件。
令 f[i][v] 表示前 i 種物品恰放入乙個容量為 v 的揹包的最大權值, 則有狀態轉移方程:
f[i][v]=max
四、分組揹包:
這個問題變成了每組物品有若干種策略:是選擇本組的某一件,還是一件都不選。
狀態方程:
for 所有的組k
for v=v…0
for 所有的i屬於組k
「for v=v…0 」這一層迴圈必須在「 for 所有的 i 屬於組 k」之外。這樣才能保證每一組內的物品最多只有乙個會被新增到揹包中。
f[k][v]=max
壓縮優化後:
f[v]=max
在解決這些問題時,我們首先要確定是哪一類揹包問題,這基本上也很容易看出,然後套用該揹包問題的演算法模板形式就容易解決問題了,不過有的題目似乎是揹包的混合問題,當然這類問題比較難,需要我們更加深入的思考。
揹包問題 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件裡面挑選一些放到乙個容量一定的揹包裡面,使得你的揹包裡的東西總價值最大。對於這些東西的每一件,你可以選擇放進你...