揹包詳解 模板

2022-08-31 15:33:14 字數 2662 閱讀 3809

揹包詳解請看

一:01揹包

特點:每種物品只有一件,可以選擇放或不放

這個方程非常重要,基本上 所有跟揹包相關的問題的方程都是由它衍生出來的。所以有必要詳細講解一下:」將前i件物品放入容量為j的揹包中「這個子問題,若只考慮第i件物品的策略(放或者不放),那麼就可以轉化為乙個只和前i-1件物品相關的問題。如果不放第i件物品,那麼問題就可以轉化為」前i-1件物品放入容量為j的揹包中「,價值為dp[i-1][j];如果放入第i件物品,那麼問題就可以轉化為」前i-1件物品放入剩下的容量為j-wi的揹包中「,此時能獲得的最大價值就是dp[i-1][j-wi],再加上通過放入第i件物品獲得的價值vi

dp[i][j]為當前需要判斷的物品,可以選擇放或者不放,不放的話價值為dp[i][j-1] ,放的話價值為dp[i-1][j-wi]+vi,比較這兩個的大小,選擇大的價值。

eg:給出n是物品數,c是揹包的容量,v[i]價值 w[i]重量

5 10

6 3 5 4 6

2 2 6 5 4

將計算出的裝入揹包物品的最大價值和最優裝入方案輸出 15

**1

#include #include #include #include #include using namespace std;

int main()

}printf("%lld",dp[n][c]);

return 0;

}

**2(降低複雜度)

#includeusing namespace std;

int dp[1005];//滾動陣列的寫法,省下空間省不去時間

int weight[1005];

int value[1005];

int main()

}cout《注意上面兩個**的區別 

第乙個dp是二維的,而第二個是一維的  第二個**j迴圈要反著寫

如何理解二維降一維呢?對於外層迴圈中的每乙個i值,其實都是不需要記錄的,在第i次迴圈時,所有的dp[0…c]都還未更新時,dp[j]還記錄著前i-1個物品在容量為j時的最大價值,這樣就相當於還記錄著dp[i-1][j]和dp[i-1][j-w[i]]+v[i]

關鍵是內迴圈中為什麼是逆序的呢,因為要記算當前狀態的dp[j],需要的是前一狀態的dp[j](即dp [j-1]),而逆序迴圈時前面的一定就是前一狀態的dp[j],可以直接拿來用,而正序迴圈之所以不可以,是因為當你計算完前面的dp[j]時,dp[j-1]存的就不是i-1時刻的值了,而你後面還要用dp[j-1]。當內迴圈是逆序時,就可以保證後乙個dp[j]和dp[j-w[i]]+v[i]是前一狀態的!

二:完全揹包

特點每種物品僅有無限件,可以選擇放或不放

memset(dp, 0, sizeof(dp));

for(int i=0; i完全揹包相比較於0-1揹包,只需要將內迴圈由逆序遍歷改為正序遍歷就好了

三:多重揹包

多重揹包問題限定了一種物品的個數,解決多重揹包問題,只需要把它轉化為0-1揹包問題即可。比如,有2件價值為5,重量為2的同一物品,我們就可以分為物品a和物品b,a和b的價值都為5,重量都為2,但我們把它們視作不同的物品。

二進位制分解思想:

例如有22個重量和價值都為1的物品,如果按照常規方法的話,需要迴圈22次,每次放入乙個重量質量都為1的物品,而用二進位制分解的話,可以將22個物品轉化為5個物品,5個物品的重量和價值為1,2,4,8,7;這樣致需要迴圈5次就可以了。

把22進行二進位制拆分:

成為1,2,4,8,7;由1,2,4,8可以組成1--15之間所有的數,而對於16--22之間的數,可以先減去剩餘的7,那就是1--15之間的數可以用1,2,4,8表示了。

#include #include #include #include #define max 1000000

using namespace std;

int dp[max];//儲存最後揹包最大能存多少

int value[max],weight[max],number[max];//分別存的是物品的價值,每乙個的重量以及數量

int bag;

void zeroonepack(int weight,int value )//01揹包

}void completepack(int weight,int value)//完全揹包

}void multiplepack(int weight,int value,int number)//多重揹包

else//否則就將多重揹包轉化為01揹包

zeroonepack(number*weight,number*value);

}}int main()

memset(dp,0,sizeof(dp));

for(i = 0; icout<}

return 0;

}

01揹包模板 完全揹包 and 多重揹包(模板)

模版就直接貼 01揹包模板 cpp view plain copy print?01揹包問題 01揹包問題的特點是,每種物品僅有一件,可以選擇放或不放。01揹包問題描述 有n件物品和乙個容量為v的揹包。第i件物品的重量是c i 價值是w i 求解將哪些物品裝入揹包可使這些物品的重量總和不超過揹包容量...

01揹包模板 完全揹包 and 多重揹包(模板)

01揹包模板 01揹包問題 01揹包問題的特點是,每種物品僅有一件,可以選擇放或不放。01揹包問題描述 有n件物品和乙個容量為v的揹包。第i件物品的重量是c i 價值是w i 求解將哪些物品裝入揹包可使這些物品的重量總和不超過揹包容量,且價值總和最大。include define n 1050017...

01揹包模板 全然揹包 and 多重揹包(模板)

模版就直接貼 01揹包模板 01揹包問題 01揹包問題的特點是,每種物品僅有一件。能夠選擇放或不放。01揹包問題描寫敘述 有n件物品和乙個容量為v的揹包。第i件物品的重量是c i 價值是w i 求解將哪些物品裝入揹包可使這些物品的重量總和不超過揹包容量,且價值總和最大。include define ...