單調佇列最佳化DP
單調佇列模板:
int head = 1,tail = 0;
for (int i = 1;i <= n;i++)
{
while (head <= tail && head 不滿足條件) head++;//踢出佇列
f[i] = f[q[head]] + ...;
while (head <= tail && tail 與 i 不滿足單調性) tail--;
q[++tail] = i;
}
最佳化思路則是對於類似於這樣的 dp 式:
\[\huge {f_i = \max _{i-M <= j <= i-1}\{ f_j + w \}}
\]
在其中求區間最值時,因為其上下限均單調變化,因此可以用單調佇列將轉移最佳化到 \(O(1)\) 。
單調佇列最佳化多重揹包
單調佇列最佳化多重揹包
思路
首先我們列出 dp 式:
\[\huge{f_j = \max_{1 \le cnt \le s _ i} \{ f _ j-cnt*v_i + cnt * w_i \}}
\]
我們考慮將第二維 \(V\) 按照除以 \(v_i\) 的餘數分組。
對於每個餘數 \(u \in [0,v_i-1]\),倒序迴圈 \(p = (V-u)/v_i\)。
因此可以寫出新的狀態轉移方程:
\[\huge{f_{u + p * v_i} = \max _{p-s_i \le k \le p-1} \{ f_{u + k * v _ i} + (p-k)*w _ i \}}
\]