揹包那些經典的例子 下

2021-08-04 05:16:23 字數 2395 閱讀 9563

補上我的上篇講解01揹包與完全揹包,這一篇講解兩個我認為比較經典的揹包題。乙個是多重揹包題,直接套模板可以ac,乙個是多重揹包與完全揹包題,需要改變一下模板。當然只要理解了揹包的核心就能輕鬆改動模板。道可道,非常道,這個核心我還是模糊到難以講出來。
簡單說一下題目:

有件商品最大**不超過m, 然後你有很多種價值不同的硬幣,且數目有限。題目問你,在1到m中的那些**中,求手中的硬幣剛好能夠支付的**(硬幣價值只有剛好等於某個**時候才行,超過了就不滿足題意了)。

題目思路:

如果對多重揹包了解的,可以很快想出來該題的解題演算法,就是乙個標準的套模板題嘛。我們看看一般的多重揹包題意。

有n種物品和乙個容量為v的揹包。第i種物品最多有n[i]件可用,每件費用是c[i],價值 是w[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。
細細品讀後,發現這個跟本題的意思基本一樣。多重揹包問題,乙個有限容量的揹包要裝下最大價值的物品,眼前由很多種物品,有一定的價值和體積,但是呢每種物品數量又是有限的。這個跟完全揹包有點不同,完全揹包是同種物品數量無限

說到這,可以知道這是乙個簡單的多重揹包題了吧,多重揹包由基礎揹包與完全揹包組成,乙個模板就能解決這一問題。當然死記模板也是不好。

下面看看代吧。

#include 

using

namespace

std;

const

int maxn = 100010;

//把一種物品的花費cost,價值weight,數目amount放在乙個結構體裡繫結起來,方便呼叫

//當然使用陣列也行,這一題,用不到cost的值,不寫也行。

struct pack

pack[maxn];

//狀態轉移的關鍵陣列f,和揹包的總容量v(也就是本題的最大價值)

int f[maxn], v;

//基礎揹包

void basepack(int cost, int weight)

//完全揹包

void competepack(int cost, int weight)

//多重揹包,前兩個揹包的組合

void multiplepack(int cost, int weight, int amount)

//不是完全揹包就是基礎揹包了

for(int k=1; k1)

basepack(amount*cost, amount*weight);

}int main()

這個輸入輸出格式就不多說了,自己找鏈結看吧。

細看題發現似乎是揹包題,而且是多重揹包題,但是又發現有乙個收銀員很礙事。這個其實就是混合揹包問題。乙個題目裡面有兩個揹包問題。

首先是顧客的硬幣數做乙個揹包問題,是多重揹包。然後收銀員找的硬幣數,因硬幣數無限,看作是完全揹包問題。

依據題意定義子問題f1[i]表示支付i價值的硬幣的最小數量,而f2[i]表示找i價值的硬幣的最小數量。

那麼怎麼求最小流動的硬幣數量。

當支付的硬幣總價值為k,k>=v。那麼f1[k]就是支付的最小硬幣數量,那麼找的硬幣的最小數量就是f2[k-v].

講解可能不清楚,那就看看下面的**自己體會一下吧。

#include 

using

namespace

std;

#define inf 0x3f3f3f3f

#define maxn 20010

struct pack

pack[maxn];

//顧客的硬幣數狀態f1, 收銀員找硬幣數目的狀態

int f1[maxn], f2[maxn], v;

//因為題目求的是最小的硬幣數目,那麼就得稍微修改一下摸板,f不再是求最大價值了,而是求最小硬幣數目

//max 變為 min ,然後是相加硬幣數目+amount 而不是加價值weight了,故而得額外加乙個引數

//這裡最大範圍不在侷限於v了,因為**可以超出,我們把範圍就定為比較大的maxn。

void basepack(int cost, int weight, int amount, int* f)

void competepack(int cost, int weight, int* f)

void multiplepack(int cost, int weight, int amount ,int* f)

for(int k=1; k1)

basepack(amount*cost, amount*weight, amount, f);

}int main()

return

0;}

經典的列題就講這四個吧,理解後能更深刻地了解三個揹包了,也能更靈活地使用模板了。

揹包那些經典的例子 上

發現自己對揹包問題還是情有獨鍾的嘛,畢竟它也算的上是我真正學到的第乙個演算法。哎,現在我還是乙個苦命掙扎的菜鳥。廢話也不多說了,下面進入正題吧,這些都是菜鳥在刷揹包題遇到的基礎問題,作為菜鳥的我就是刷這些題一步一步理解揹包的。01揹包問題 bone collector hdu 2602有n件物品和乙...

經典揹包問題 01揹包 完全揹包 多重揹包

1 for int i 0 i 2for int j w j size i j 3 f j max f j f j size i value i 1 for int i 0 i 2for int j size i j w j 3 f j max f j f j size i value i f w ...

經典的揹包問題

揹包問題i 難度級別 b 執行時間限制 1000ms 執行空間限制 51200kb 長度限制 2000000b 試題描述 有乙個揹包容積為 v 和 n 個物品,並給出每個物品有乙個體積。要求從 n 個物品中,任取若干個裝入揹包內,使揹包的剩餘空間為最小。輸入第一行兩個正整數 v 和 n,分別表示揹包...