(長期更新)DP 學習筆記

huangkxQwQ發表於2024-10-09

DP 的本質

一般 DP 的本質

  • 狀態:點。(帶了值)
  • 轉移:邊。
  • DP:在 DAG 上推。(得到 / 更新 點的值)

特殊(類似 DP)

圖不是 DAG。有兩種思路:

  • 解方程
    • 簡單的:直接解(比如只有一個環)。
    • 複雜的:高斯消元。
      • 高斯消元。
      • 高斯-約旦消元。
  • 圖論
    • 類似最短路:
      • Dijkstra 演算法 / 類似 Dijkstra 的演算法。
      • SPFA 演算法 / 類似 SPFA 的演算法。
    • 其他的我可能還不知道。

DP 的要素

(我目前想起來的。)

  • 狀態。無後效性,設計方式:把之後要用的全部塞進狀態裡。
  • 轉移方程。就近轉移,不重不漏。最值(min、max)、其他運算。
  • 初值。按定義 / 為了轉移後得到的狀態的值正確。[也許要為了之後正確用奇怪的定義。](?)(好像是 重返現世 那題)。[注意特殊情況。](之前寫的,現在不知道例子是什麼)
  • 最終答案。可能是一個狀態,可能是多個狀態運算起來。

可能一般按 狀態 -> 轉移方程 -> 初值、最終答案 的順序思考。

DP 的轉移方式

之前聽說叫“填表法”和“刷表法”。

推到其他狀態

在當前狀態上做改動。個人認為更符合正向思維。

似乎轉移對應關係複雜的時候用這種方式比較清晰方便。

從其他狀態轉移來

找之前的狀態。個人認為更符合逆向思維。

似乎更常用。

似乎在決策方面最佳化 DP 的時候常用。比如 單調棧、單調佇列、斜率、決策單調性、線段樹之類的 DS 大力找決策點 最佳化 DP。

DP 的轉移順序

按拓撲序

(我知識水平非常有限,不太瞭解拓撲序,這裡說拓撲序可能不止一種是不嚴謹的或錯誤的,但是就是這個意思 qwq。)

一般的轉移順序。本質上是按照 DAG 的拓撲序。

注意拓撲序可能不止一種,有時換一種順序可能可以最佳化 DP,換順序如:二維狀態的 DP,先列舉哪一維後列舉哪一維可能可以顛倒。(如:把序列分割成給定個數個區間的題。)

記憶化搜尋

避免了轉移順序的問題。

注意初始化 \(vis\) 陣列(或者直接把 \(f\) 初始化成 \(-1\) 之類的)。

時間複雜度[一般要](?)結合狀態數來分析,但不一定等於狀態數,可能還要算上轉移和其他的代價。(如二維區間 DP。)

典型例子是數位 DP、二維區間 DP。

相關文章