如果將p01、p02、p03混合起來。也就是說,有的物品只可以取一次(01揹包),有的物品可以取無限次(完全揹包),有的物品可以取的次數有乙個上限(多重揹包)。應該怎麼求解呢?
考慮到在p01和p02中給出的偽**只有一處不同,故如果只有兩類物品:一類物品只能取一次,另一類物品可以取無限次,那麼只需在對每個物品應用轉移方程時,根據物品的類別選用順序或逆序的迴圈即可,複雜度是o(vn)。偽**如下:
for i=1..n如果再加上有的物品最多可以取有限次,那麼原則上也可以給出o(vn)的解法:遇到多重揹包型別的物品用單調佇列解即可。但如果不考慮超過noip範圍的演算法的話,用p03中將每個這類物品分成o(log n[i])個01揹包的物品的方法也已經很優了。if 第i件物品屬於01揹包
for v=v..0
f[v]=max;
else if 第i件物品屬於完全揹包
for v=0..v
f[v]=max;
當然,更清晰的寫法是呼叫我們前面給出的三個相關過程。
for i=1..n在最初寫出這三個過程的時候,可能完全沒有想到它們會在這裡混合應用。我想這體現了程式設計中抽象的威力。如果你一直就是以這種「抽象出過程」的方式寫每一類揹包問題的,也非常清楚它們的實現中細微的不同,那麼在遇到混合三種揹包問題的題目時,一定能很快想到上面簡潔的解法,對嗎?if 第i件物品屬於01揹包
zeroonepack(c[i],w[i])
else if 第i件物品屬於完全揹包
completepack(c[i],w[i])
else if 第i件物品屬於多重揹包
multiplepack(c[i],w[i],n[i])
有人說,困難的題目都是由簡單的題目疊加而來的。這句話是否公理暫且存之不論,但它在本講中已經得到了充分的體現。本來01揹包、完全揹包、多重揹包都不是什麼難題,但將它們簡單地組合起來以後就得到了這樣一道一定能嚇倒不少人的題目。但只要基礎紮實,領會三種基本揹包問題的思想,就可以做到把困難的題目拆分成簡單的題目來解決。
混合揹包問題
name 混合揹包問題 author 巧若拙 date 07 06 18 09 33 description 混合揹包問題 在n種物品中選取若干件放在容量為c的揹包裡,分別用p i 和w i 儲存第i種物品的價值和重量。有的物品只可以取一次 01揹包 有的物品可以取無限次 完全揹包 有的物品可以取的...
混合揹包問題
有 n 種物品和乙個容量是 v 的揹包。物品一共有三類 第一類物品只能用1次 01揹包 第二類物品可以用無限次 完全揹包 第三類物品最多只能用 si 次 多重揹包 每種體積是 vi,價值是 wi。求解將哪些物品裝入揹包,可使物品體積總和不超過揹包容量,且價值總和最大。輸出最大價值。輸入格式 第一行兩...
混合揹包問題
題面連線 題面有 n 種物品和乙個容量是 v 的揹包。物品一共有三類 每種體積是 vi 價值是 wi 求解將哪些物品裝入揹包,可使物品體積總和不超過揹包容量,且價值總和最大。輸出最大價值。輸入格式 第一行兩個整數,n,vn,v,用空格隔開,分別表示物品種數和揹包容積。接下來有 n 行,每行三個整數 ...