/*
樸素更新
for (int i = 0; i < n; i++)
由 f[j] = max(f[j], f[j-v] + w, f[j-2*v] + 2*w, ...);
可以觀測到 f[j] f[j-v] f[j-2v] ... f[r] (r = j % v)是一類,即後面的j只會通過同類的前面元素遞迴過來
因此可以分成如下幾類
f[0] f[v] f[2v] ... f[kv];
f[1] f[1+v] f[1+2v] ... f[1+kv];
...f[r] f[r+v] f[r+2v] ... f[r+kv];
其中 0 <= r < v;
所以我們可以從0到r遍歷更新每一類。
此外還有乙個限制。f[j] 需要借助 f[j-v] .. f[j-s*v] 這些元素更新,並不是同類所有元素,而是乙個長度為s的視窗
因此可以用滑動視窗在o(n)的時間內對一類物品進行更新
同時由於用滑動視窗需要從前往後更新,而滾動陣列的更新順序正好相反,所以需要在維護乙個備份陣列,每次更新f前把f的
內容拷貝到g中。只用g來更新。
單調佇列中儲存的元素是什麼?
由f[j] = max(f[j], f[j-k*v] + k * w) (1 <= k <= s)可知
當更新g[j](f[j])時,單調佇列中儲存的是另 f[i-k*v]+k*w (1 <= k <= s)
最大的元素k。
*/#include
#include
using
namespace std;
const
int n =
20010
;int f[n]
, g[n]
, q[n]
;int
main()
}}cout << f[m]
<< endl;
return0;
}
多重揹包單調佇列優化思路 單調佇列優化多重揹包問題
6.多重揹包問題 iii acwing題庫 www.acwing.com 揹包九講bilibili www.bilibili.com 從公式中可以看出f j 和f j c 都是從s 1個數裡面取最大值,計算f j c 時只是將滑動視窗右移了一步,類似下圖的效果 只不過移動的時候,前面的s個元素都增加...
單調佇列優化多重揹包
多重揹包的最原始的狀態轉移方程 令 c i min num i j v i f i j max f i 1 j k v i k w i 1 k c i 這裡的 k 是指取第 i 種物品 k 件。如果令 a j v i b j v i 那麼 j a v i b.這裡用 k 表示的意義改變,k 表示取第...
單調佇列優化多重揹包
多重揹包 n個物品,揹包承重m,每個物品 重量 wi 價值vi 個數為ci 普通多重揹包複雜度 o nmc for int i 1 i n i for int j 1 j m j for int k 1 k c i k w i j k f i j max f i j f i 1 j k w i k ...