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

  • 相关阅读:
    【GoLand】分享项目到Github平台
    【Git】实用教程
    【Go】Mac系统下安装GoLand 及 环境配置
    CF 901C Bipartite Segments
    CF 811E Vladik and Entertaining Flags
    Luogu P6300 悔改
    Luogu P3943 星空
    CSP2020 | T4
    NOIP2017 | D2T3
    Luogu P6852 Mex
  • 原文地址:https://www.cnblogs.com/BaseAI/p/13371241.html
Copyright © 2011-2022 走看看