01揹包 絕對看得懂版

2021-10-01 13:47:32 字數 3102 閱讀 3043

有n件物品和乙個大小為m的揹包,以及若干物品,每種物品只有一件,大小分別為w[i],其價值分別為val[i]。問題:將哪些物品裝入揹包,可使得揹包內的物品價值總和最大?

輸入:第一行:n m

接下來n行,每行兩個整數,w[i]和val[i]。

輸出:最大價值vmax.

由於每種物品都只有一件,所以只存在兩個選擇:裝這個物品或者不裝。(也就是0/1揹包的含義)

我們定義乙個陣列bag [i] [v]用於儲存——當揹包大小為v,且選擇處理完第i個物品後(前i個物品選擇裝或不裝)的最大價值總和,那麼最終的答案就是bag [n] [m]。

我們通過乙個例子來推出bag [i] [v]的遞推式。

有3個物品,大小價值如下表,和乙個大小為3的揹包。

物品/揹包大小12

3a,大小1,價值2

b,大小2,價值5

c,大小1,價值3

先考慮裝不裝a。如下表。

物品/揹包大小12

3a,大小1,價值222

2b,大小2,價值5

c,大小1,價值3

由於a的大小只有1,所以大小1~3的揹包都可以裝下它,於是更新所有值為a的價值2。

接下來考慮b。如下表。

物品/揹包大小12

3a,大小1,價值222

2b,大小2,價值525

7c,大小1,價值3

由於b的大小為2,所以大小為1的揹包裝不下它,值不變。

大小為2的揹包可裝下它,且值為5,比原來的2大,於是更新值為5。

大小為3的揹包可裝下它,且裝完後剩餘大小為1。

如果裝b,那麼價值=b的價值+未裝b的、大小為1的揹包的最大價值=5+2=7。

如果不裝b,那麼價值就是原來的值=2。在二者裡取max,就能得到最大值,也就是7。

最後考慮c。如下表。

物品/揹包大小12

3a,大小1,價值222

2b,大小2,價值525

7c,大小1,價值335

8c的大小為1,揹包1可裝,值更大,更新為3。

揹包2可裝,如果裝,那麼價值=c的價值+未裝c的、大小為1的揹包的最大價值=3+2=5。

如果不裝,值就是原來的5。二者取max即可。

揹包3可裝,如果裝,那麼價值=c的價值+未裝c的、大小為2的揹包的最大價值=5+3=8。

如果不裝,值就是原來的7。二者取max即可。

所以最後輸出的值就是8。

小結論:

我們可以發現遞推公式:bag [i] [v] = max ( bag [i-1] [v] , bag [i-1] [ v - w [i] ] + val [i] )。

也就是處理第i件物品,揹包大小為v時的最大價值,有兩種可能。

①裝入第i件物品

那麼價值=該物品的價值+未裝入該物品的、大小足夠塞入該物品的揹包的最大價值=bag [i-1] [ v - w [i] ] + val [i]。

②不裝入第i件物品

那麼價值就是處理i-1件物品時計算出來的值,不變。

二者取最大值即可。

#include int max(int a,int b)``

int bag[1000][1000];//儲存解的陣列

int w[1000],val[1000];//每件物品的大小與價值

int main()

通過1.3的**可以很容易的看出,當物品有1,000件,揹包大小為1,000時,我們就需要開乙個1,000,000大小的陣列了,要是處理的資料再稍微大一點,就會導致陣列開的過大,然後記憶體溢位。

所以為了解決更大的資料,空間的優化是必要的。

我們可以發現,當我們處理第i件物品時,要用到的只是處理第i-1件物品時的資料,再之前的就用不到了。

所以,我們可以每次處理物品時,就把資料進行一次覆蓋,這樣二維陣列就能降維到一維了。

但需要注意!降維到一維陣列後,我們處理第i件物品時,就不能從大小為1的揹包一直順序處理到大小為m的揹包了。為什麼?因為這樣的話,處理i-1件物品時的資料會在本次處理中被覆蓋,而處理更大的揹包時是會用到小揹包的資料的。

這樣就會出現——已經塞了第i件物品了,處理時就當做沒塞,就會wa了。

所以我們這裡進行倒序處理,因為處理小揹包用不到大揹包的資料,覆蓋了也就覆蓋了,無所謂。

#include

intmax

(int a,

int b)

int bag[

1000];

//降維到一維的陣列

int w[

1000

],val[

1000];

//每件物品的大小與價值

intmain()

優化完後,空間複雜度就從o(t*n)縮小到了o(n),大大節省了記憶體,也就可以處理更大的資料了。

有m株藥草,每株藥草有其對應的價值及採摘該藥草要花費的時間,在n時間內,求採摘的藥草的最大價值。

這其實就是換了個題幹的0/1揹包模板題,上面的**直接複製貼上就可ac。

你有n元錢,有m種物品,每種一件,每件物品都有對應的**,並且你對每件物品都賦予了乙個重要度(從1~5),求購買的物品的最高價效比和。

注:價效比=物品***重要度。

依然是換了個題幹的0/1揹包模板,只要把價值的計算變成物品***重要度即可(val[i] = w[i] * rank [i] )。

有乙個容量為v的箱子,和n個物品,每個物品的體積為整數,裝任意個物品,問剩餘的最小體積是多少?

本題中,物品的價值與消費相同,也就是w[i]==val[i],代換進原來的**即可。

注意最後輸出的是剩餘的最小體積,故應當輸出v-bag[v]。

你有n元錢,有m種菜,每種只有乙份,且有對應的**。要求你把所有的錢都花光,問有多少種不同的點菜方案?

如果只有0元錢,那只有一種點菜方式——啥都不點。

接下來的遞推公式為bag[money]+=bag[money - w[i] ]。

即花n元的點菜方式 = 花(n-某道菜**)元錢的點菜方式的和。

揹包 01揹包

01揹包 有n種物品與承重為m的揹包。每種物品只有一件,每個物品都有對應的重量weight i 與價值value i 求解如何裝包使得價值最大。dp i,v 表示前i個物體 包括第i個 面對容量為v的揹包的最大價值,c i 代表物體i的重量,w i 代表物體i的價值 如果第i個物體不放入揹包,則揹包...

揹包專題 01揹包

暑假集訓開始了,按照隊裡的分配,我是弄dp的,嘛,於是我又一次的開始了從01揹包開始學習,昨天將杭電的幾道01揹包重新做了一遍,下面講講我自己對於01揹包的理解。首先01揹包題目的雛形是 有n件物品和乙個容量為v的揹包。第i件物品的費用是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。...

01揹包,完全揹包

動態規劃 動態規劃的核心是狀態以及狀態轉移方程。需要定義乙個 i,j 狀態以及該狀態的指標函式d i,j 01揹包 有n種物品,每種只有乙個,第i件物品的體積為vi質量為wi。選一些物品裝到體積為c的揹包中,使其體積不超過c的前提下重量最大。namevw abcd e 子問題定義 dp i j 表示...