反贡献 dp 总结
CF1810G
最大前缀和倒着做,能有个 \(\max(*-1,0)\) 形式的转移,而正着做要记录 当前和 与 当前最大前缀和 两个变量,不可接受。
所以最大前缀和题倒着做:
设 \(f_{i,j}\) 为当前考虑了 \([i, n]\),其最大前缀和为 \(j\)。有转移:
\(\begin{cases} p_i f_{i+1,j} \to f_{i,j+1} \\[5pt] (1 - p_i) f_{i+1,j} \to f_{i,\max(j-1,0)} \end{cases}\)
初值为 \(f_{n+1,0} = 1\),最终 \(ans = \sum\limits_{i=0}^{n} h_i f_{1,i}\)。
我们算的是只是长度为 \(n\) 的答案,我们希望对于每个长度 \(l\) 都求出答案,但是直接做是 \(\mathcal{O}(n^3)\) 的。
注意到我们每次 dp 的转移都是固定的,只是初值不同(长度为 \(l\) 时 dp 初值为 \(f_{l+1,0} = 1\)),因此 \(f_{i,j}\) 对答案的贡献也是固定的。
我们不妨使用 反贡献 dp 的 trick,设 \(g_{i,j}\) 为 \(f_{i,j}\) 对 \(ans\) 的贡献系数,那么有转移:
\[g_{i+1,j} = p_i g_{i,j+1} + (1 - p_i) g_{i,\max(j-1,0)}
\]
初值为 \(g_{1,i} = h_i\)。最终长度为 \(l\) 的答案为 \(g_{l+1,0}\)。时间复杂度降至 \(\mathcal{O}(n^2)\)。
CF2018F3
这题最后一步 \(n^4\to n^2\)。

浙公网安备 33010602011771号