学习报告-论对“动态规划方程优化”的新理解
学习报告-论对“动态规划方程优化”的新理解
我们在做动态规划题的时候,很容易遇到一个方程含了一大堆量,这让我们除了暴力转移没有其它方法。但是如果我们把当前的方程简化,就会发现当前方程具有某种规律,从而让我们用更优的方式进行 \(dp\)。
今天刚开始学习斜率优化的时候,上来的一道例题的普通方程放了一大堆量,并且转移范围是 \(1\sim i-1\),这让我们不得不 \(O(n^2)\) 去做。
方程大概是长这样的:
\[f_i=\min_{j=1}^{i-1}f_j+(i-j-1+pre_i-pre_j-L)^2
\]
仔细观察这个方程,发现它可以通过合并同类项的方式简化。这是简化方程的第一个思想。
我们设 \(s_i=pre_i+i,L'=L+1\),这样方程就消去了很多常数和很多不必要的项,变成了这样:
\[f_i=\min_{j=1}^{i-1} f_j+(s_i-s_j+L')^2
\]
观察这个方程,发现里面有一个 \(\min_{j=1}^{i-1}\),这种形式一般都是线段树优化 \(dp\),但是很难受的一点就是这个方程带二次,而线段树优化 \(dp\) 的方程一般都要求一次。
那么这个时候就引出了斜率优化 \(dp\)。考虑一条直线 \(y=kx+b\),其里面其实是有一个二次项(\(kx\))的,那么就可以优化这个方程。这里还没学。
回顾以前学习线段树优化 \(dp\) 的时候,真的存到线段树每一个结点里的就是 \(f_i\),不加东西,不减东西?不是的,我们还是要设一个 \(g_i=f_i+\dots\),然后把 \(g_i\) 存进去,调用出来的也是 \(g_i\)。
进一步推导,不同的 \(dp\) 方程有不同的合并同类项的方法,合并出来对应的次数或其他特征也不同,那么对应的优化方案也不同。但是记住一点:\(dp\) 式子如果有时间复杂度优化,为什么你没看出来?就是因为你没有对 \(dp\) 式子本身进行优化。