學習來自b站up講解的01揹包問題後寫下的總結
有n件物品,每件物品的重量為w[i],價值為c[i]。現有乙個容量為v的揹包,問如何選取物品放入揹包,使得揹包內物品的總價值最大。其中
每種物品都只有一件。
令dp[i][j]來表示前i件物品裝入容量為j的揹包所能得到的最大總價值。
對於dp[i][j]來說,i指的是前i件物品,j指的是還剩下多少揹包空間。於是對於dp[i][j]來說,有公式
編號i重量w[i]
**v[i]
揹包容量 w = 2012
3234
3454
5859
10 **(即這個過程本質是填寫下面的這個**):
capacity=> 01
2345
6789
1011
1213
1415
1617
1819
20no items00
0000
0000
0000
0000
000w=2 v=3 00
3333
3333
3333
3333
333w=3 v=400
3447
7777
7777
7777
777w=4 v=500
3457
89912
1212
1212
1212
1212
1212
12w=5 v=800
3458
8111213
1516
1717
2020
2020
2020
20w=9 v=1000
3458
8111213
1516
1717
2020
2122
2325
26**標紅的地方就是我們要求的dp[5][20]
接下來對**每個位置進行說明,那第一行來說,表示的是前0件物品,揹包容量為0~20時可以放進去的最大價值,物品都沒有,不管容量多大可以容納的價值都是0;
同樣的,比如第二行,表示前1件物品(此物品重量為2,價值為3)在揹包剩餘容量為0時,放不下去,此時最大價值是0;揹包剩餘容量是1時,放不下去,此時最大價值是0;揹包剩餘容量為2時,能放進去,此時最大價值是3···
那麼到了第3行(前2件物品),在揹包容量是5的時候,為了達到最大價值,可以把第1件和第2件商品都放進去,5 >= 2 + 3,可以放下,最大價值為3 + 4 = 7。
整個**的填寫由程式來完成,計算公式為上面所列出的dp[i][j]計算公式。最後只需要取出我們所需要的dp[5][20]即可得到前5件物品,揹包容量為20時的最大價值。
下面是程式
#include #define n 6
#define m 21
#define w 20
int dp[n][m];
int w[n] = ;
int v[n] = ;
void knapsack()
else
} }}
int main()
#include #define maxn 100 // 物品最大件數
#define maxv 1000 // v的上限
int w[maxn], c[maxn], dp[maxv];
int main()
for(i = 0; i < n; i++)
// 邊界
for(v = 0; v <= v; v++)
for(i = 1; i <= n; i++)
} // 尋找dp[0...v]中的最大即為答案
max = 0;
for(v = 0; v <= v; v++)
printf("%d\n", max);
return 0;
}
揹包問題 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...