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

  • 相关阅读:
    POJ 3687 Labeling Balls()
    POJ 2777 Count Color(线段树之成段更新)
    POJ 1961 Period( KMP )*
    POJ 2406 Power Strings (KMP)
    hdu 2199 Can you solve this equation?(二分搜索)
    10679 多少个1
    POJ 2823 Sliding Window
    POJ 2299 Ultra-QuickSort(线段树入门)
    最短路径—Dijkstra算法和Floyd算法
    poj1125&zoj1082Stockbroker Grapevine(Floyd算法)
  • 原文地址:https://www.cnblogs.com/BaseAI/p/13371241.html
Copyright © 2011-2022 走看看