1. 程式人生 > 其它 >AcWing 6.多重揹包問題III

AcWing 6.多重揹包問題III

題目傳送門

\(n\)個物品, 揹包容量為\(m\)

假設第\(i\)個物品體積為\(v\), 價值為\(w\), 個數為\(s\)

\(f[i, j ] = f[i-1, j-v]+w, f[i-1, j-2v]+2w, f[i-1, j-3v] +3w, f[i-1, j-4v]+4w, ... f[i-1,j-sv]+sw\)
\(f[i, j-v] =\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ f[i-1, j-2v]+w,f[i-1,j-3v] +2w, f[i-1, j-4v]+3w, ... f[i-1, j-(s+1)v] + sw\)


\(f[i, j-2v] =\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ f[i-1, j-3v]+w , f[i-1, j-4v]+2w, ...f[i-1, j-(s+2)v] + sw\)

設m % v = d 變換下上面式子可以得出,

f[i, d] = f[i-1][d]
f[i, d+v] = max(f[i-1, d] +w, f[i-1, d+v]) = max(f[i-1, d], f[i-1, d+v]-w) + w
f[i, d+2v] = max(f[i-1, d] +2w, f[i-1, d+v] +w, f[i-1, d+2v]) = max(f[i-1, d], f[i-1, d+v]-w, f[i-1, d+2v]-2w) + 2w
f[i, d+3v] = max(f[i-1, d] +3w, f[i-1, d+v] +2w, f[i-1, d+2v]+w, f[i-1, d+3v]) = max(f[i-1, d], f[i-1, d+v]-w, f[i-1, d+2v]-2w, f[i-1, d+3v]-3w) + 3w
f[i, d+4v] = max(f[i-1, d] +4w, f[i-1, d+v] +3w, f[i-1, d+2v]+2w, f[i-1, d+3v]+w, f[i, d+4v])

我們發現對於體積 j,j % v = d的話,j的狀態僅由體積 % v 也等於d的狀態轉移而來, 比如d+3v, 僅由體積為d+v, d+2v, d這些狀態轉移, 這些體積 % v都等於d,我們將之前的狀態
放入單調佇列即可, 放入時,有個技巧,放入 f[i-1, d+ jv] - jw 而不是 f[i-1, d+ jv] ,看看上面的式子就知道為啥了,是為了利用之前的結果。 我們減去再加回來就能保證當前狀態最後的答案正確了。

第0次 f[i, d] = f[i-1, d] 入隊
第1次 f[i-1, d+v]-w 進佇列與佇列之前的數字比較
第2次 f[i-1, d+2v]-2w 進佇列與佇列之前的數字比較
第j次 f[i-1, d+jv]-jw 進佇列與之前佇列中的數字比較

所以我們列舉i個物品
列舉餘數d
列舉j即可, 用於判斷體積為d + jv的時候,揹包能裝滿的最大值 由上面式子發現可以用單調佇列處理重複項

有個小細節,由於物品個數有限制我們要加個陣列儲存 佇列中狀態對應的編號j