01揹包問題

2021-10-22 20:28:18 字數 2198 閱讀 5404

最開始接觸這道題是:

給定乙個陣列a(至少1個元素,最多50個元素,且101≤ a[is 300),a[i]表示第i個貨物的重量。每個揹包的最大容量為300。每個揹包可裝多個貨物,但不能超過其容量。

輸入:陣列a

輸出:能裝下所有貨物所需的最少揹包數量。

這個題就很簡單,只需要判斷裝入揹包的貨物的重量不超過容量即可(貨物不可拆分)

思路:因為乙個揹包可以裝多個貨物,這時候就要看其裝入的重量是多少了,這時候就需要用乙個變數sum來儲存了,然後再判斷其是否超過最大容量,如果超過,那就需要裝入別的袋子中。裝入別的袋子的重量就是最後加入的貨物的重量(不是從0開始了)。

其實我這麼做會有乙個問題就是,如果貨物是沒排好序的,那麼就可能出現容量沒有充分利用,但是解決這個問題的方法很簡單,就是在判斷前先對貨物的重量排個序,就不會出現以上情況了。

改正後的**:

上面的題已經解答完畢了,但是在我搜尋揹包問題的時候,結果卻不是這個問題,但是我還是了解了一下,相當於是此問題的提公升,有興趣的也可以了解一下。

此題我覺得有兩個博主講的很清楚了,可以參考參考:

這兩個博主講的還是很清楚的,但是我還是看了很久,主要原因還是在看錶的地方,下面講講我對錶的理解。

一、初始化邊界為0的原因:1.第一行是因為虛構的物品序號為0,所以第一行全為0,;2.第一列全為0是因為在揹包容量為0的情況下,裝不了任何東西,也就是說價值為0;

二、判斷條件:剛開始沒看明白是因為沒明白j的含義是什麼,現在明確了,整個大問題可以分成小問題,然後找遞推的關係。此問題就可分解為揹包的容量為j時,裝入的貨物的最大價值。

所以先給定j的值,然後填表。這個時候問題的關鍵來了,兩個表示式:

1.j2.j>=w(i) v(i,j)=max{v(i-1,j),v(i-1,j-w(i))+v(i)}

第二個是當容量允許的時候,不能直接裝入,要判斷裝入和不裝入誰的價值更大。而裝入後的價值是自身的價值與其容量減去貨物重量剩餘的量的上乙個貨物的最大價值之和。

按照這兩個表示式,這個表就能完成了,表完成以後就很清楚了。

表完成以後就能找出最大價值了,然後再通過回溯法去找到其對應的貨物。

#includeusing namespace std;

#include int w[5] = ; //商品的體積2、3、4、5

int v[5] = ; //商品的價值3、4、5、6

int ba** = 8; //揹包大小

int dp[5][9] = }; //動態規劃表

int item[5]; //最優解情況

void findmax() }}

void findwhat(int i, int j)

else if (j - w[i] >= 0 && dp[i][j] == dp[i - 1][j - w[i]] + v[i]) }}

void print()

cout << endl;

} cout << endl;

for (int i = 0; i < 5; i++) //最優解輸出

揹包問題 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...