P04 混合三種揹包問題

2021-07-26 18:15:19 字數 1013 閱讀 1577

如果將p01、p02、p03混合起來。也就是說,有的物品只可以取一次(01揹包),有的物品可以取無限次(完全揹包),有的物品可以取的次數有乙個上限(多重揹包)。應該怎麼求解呢?

考慮到在p01和p02中給出的偽**只有一處不同,故如果只有兩類物品:一類物品只能取一次,另一類物品可以取無限次,那麼只需在對每個物品應用轉移方程時,根據物品的類別選用順序或逆序的迴圈即可,複雜度是o(vn)。偽**如下:

for i=1..n

if 第i件物品屬於01揹包

for v=v..0

f[v]=max;

else if 第i件物品屬於完全揹包

for v=0..v

f[v]=max;

如果再加上有的物品最多可以取有限次,那麼原則上也可以給出o(vn)的解法:遇到多重揹包型別的物品用單調佇列解即可。但如果不考慮超過noip範圍的演算法的話,用p03中將每個這類物品分成o(log n[i])個01揹包的物品的方法也已經很優了。

當然,更清晰的寫法是呼叫我們前面給出的三個相關過程。

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揹包、完全揹包、多重揹包都不是什麼難題,但將它們簡單地組合起來以後就得到了這樣一道一定能嚇倒不少人的題目。但只要基礎紮實,領會三種基本揹包問題的思想,就可以做到把困難的題目拆分成簡單的題目來解決。

P04 混合三種揹包問題

如果將p01 p02 p03混合起來。也就是說,有的物品只可以取一次 01揹包 有的物品可以取無限次 完全揹包 有的物品可以取的次數有乙個上限 多重揹包 應該怎麼求解呢?考慮到在p01和p02中給出的偽 只有一處不同,故如果只有兩類物品 一類物品只能取一次,另一類物品可以取無限次,那麼只需在對每個物...

P04 混合三種揹包問題

如果將p01 p02 p03混合起來。也就是說,有的物品只可以取一次 01揹包 有的物品可以取無限次 完全揹包 有的物品可以取的次數有乙個上限 多重揹包 應該怎麼求解呢?考慮到在p01和p02中給出的偽 只有一處不同,故如果只有兩類物品 一類物品只能取一次,另一類物品可以取無限次,那麼只需在對每個物...

P04 混合三種揹包問題

如果將p01 p02 p03混合起來。也就是說,有的物品只可以取一次 01揹包 有的物品可以取無限次 完全揹包 有的物品可以取的次數有乙個上限 多重揹包 應該怎麼求解呢?考慮到在p01和p02中給出的偽 只有一處不同,故如果只有兩類物品 一類物品只能取一次,另一類物品可以取無限次,那麼只需在對每個物...