C 01揹包問題

2022-03-11 21:42:21 字數 1333 閱讀 5634

有n件物品和乙個容量為v 的揹包。放入第\(i\)件物品耗費的空間是\(c_i\),得到的價值是\(w_i\)。求解將哪些物品裝入揹包可使價值總和最大。

這是最基礎的揹包問題,特點是:每種物品僅有一件,可以選擇放或不放。 用子問題定義狀態:即\(f[i,v]\)表示前i件物品恰放入乙個容量為v的揹包可以獲得的最大價值。則其狀態轉移方程便是:

\(f_ = \max\, f_ + w_i\}\)

memset(f[0], 0, sizeof(f[0]));

for (int i = 1; i <= n; ++i)

}for (int i = 0; i <= v; ++i) ans = max(ans, f[n][i]);

其時間複雜度和空間複雜度都是\(o(nv)\), 其中時間複雜度基本上不能再優化了,但空間複雜度卻可以優化到\(o(v)\)。

memset(f, 0, sizeof(f));

for (int i = 1; i <= n; ++i)

}for (int i = 0; i <= v; ++i) ans = max(ans, f[i]);

看一道題:小a點菜

對於這類改變問法的問題,一般只需將狀態轉移方程中的\(max\)改成\(sum\)即可。例如若每件物品均是完全揹包中的物品,轉移方程即為

\(f[i,v] = sum\\)

初始條件是\(f[0,0] = 1\)。

f[0][0] = 1;

for (int i = 1; i <= n; ++i)

}ans = f[n][v];

printf("%d\n", ans);

再看一題:裝箱問題 [noip2001普及組第4題]

其實這裡\(w_i\)就是\(c_i\)。

memset(f, 0, sizeof(f));

for (int i = 1; i <= n; ++i)

}for (int i = 0; i <= v; ++i) ans = max(ans, f[i]);

printf("%d\n", v - ans);

又來一題:積木城堡

求出每個高度的城堡數量。

for (int i = 0; i < n; ++i) 

if (max_sum < sum) max_sum = sum;

memset(f, 0, sizeof(f));

f[0] = 1;

for (int j = 1; j <= np; ++j)

} }}

C 0 1揹包問題

0 1揹包問題 0 1揹包問題基本思想 p i,j 表示在前面i個物品總價值為j時的價值最大值。str i,j 表示在前面i個物品總價值為j時的價值最大值時的物品重量串。i 0 或者j 0時 p i,j 0 str i,j 第i件物品的在重量小於j時能夠放入揹包 p i,j p i 1,j w i ...

C 01揹包問題

01揹包問題 有n個重量和價值分別為wi,vi的物品。從這些物品中挑選出總重量不超過w的物品,求所有挑選方案中價值總和的最大值 輸入格式 nw v w輸出格式 價值總和最大值 輸入 42 3 1 23 4 2 25 輸出 7解題思路 對每個物品有兩種選擇,選或者不選。選擇該物品的話,總價值會增加,剩...

揹包問題詳解(c ) 01揹包

有 n 件物品和乙個容量是 v 的揹包。每件物品只能使用一次。第 i件物品的體積是 v,價值是 wi。求解將哪些物品裝入揹包,可使這些物品的總體積不超過揹包容量,且總價值最大。輸出最大價值。第一行兩個整數 n,v用空格隔開,分別表示物品數量和揹包容積。接下來有 n 行,每行兩個整數 vi,wi用空格...