线性dp小总结

前言

2020暑假,回归OI。这两个dp难度比较低,但有一定价值,写个归纳总结。

线性dp小总结(优化)

洛谷P4933 大师

题目地址

看懂题目后,容易列出dp方程:

  • \(f(i,j)\) 表示以 \(i\) 结尾,公差为 \(j\) 的等差数列方案数。

\[f(i,j) = \sum_{\{k | h_i - h_k = j\}} f(k,j) \]

状态是 \(O(n^2)\) 的,转移是 \(O(n)\) 的,我们必须有一些优化。发现转移就是要对 \(i\) 前面所有满足 \(h_k = h_i - j\)\(f(k,j)\) 求和。

于是我们枚举公差 \(j\)

  • 令函数 \(g(x) = \sum_{\{k|h_k=x,k<i\}} f(k,j)\)

  • 则有 \(f(i,j) = g(h_i-j)\)

\(g(x)\) 可以在dp的过程中累积,转移便优化成了 \(O(1)\)

总结:对于dp转移过程中如果遇见了求和,试着发现求和式子的规律,设计函数(并且该函数可以在dp过程中累积),从而降低转移的复杂度。

洛谷 P5858 「SWTR-03」Golden Sword

题目地址

看懂题目后,容易列出dp方程:

  • \(f(i,j)\) 表示以 \(i\) 结尾,当前原材料为 \(j\) 的最大耐久度

\[f(i,j) = \max_{j-1 \le k \le j+s} \{ f(i-1,k) \} + a_i*j \]

状态是 \(O(n^2)\),转移是 \(O(n)\),我们必须有一些优化。试着模拟 \(j\) 的枚举,发现 \(j\)\(0 \le j \le w\) 移动的过程中 \([j-1,j+s]\) 也在向右移动。我们需要的就是这个移动区间的最大值。至此,我们发现这个转移可以使用单调队列实现 \(O(1)\) 转移。

如果在dp转移过程中遇见了求最值,试着发现最值区间的变化规律,尝试利用数据结构优化,从而降低转移的复杂度。

posted @ 2020-07-24 12:04  基地AI  阅读(209)  评论(0编辑  收藏  举报