线性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转移过程中遇见了求最值,试着发现最值区间的变化规律,尝试利用数据结构优化,从而降低转移的复杂度。

原文地址:https://www.cnblogs.com/BaseAI/p/13371241.html