演算法隨筆——DP最佳化

codwarm發表於2024-07-21

單調佇列最佳化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 \}} \]

相關文章