dp的本質

  什麼是真正的dp?有什麼特色?怎麼來搞。算法

最近遇到了一些之前的題目發現沒有好好的理解就直接寫了 大多都是書上的算法並非本身真正的理解。數組

1 關於揹包 我總結一下 可能 有助於對模型的更快發現優化

01 揹包 通常來講直接使用一個維度直接繼承上一層的狀態 對於每個狀態咱們能夠保證其實最優的因此具備最優子結構因此 是正確的。設計

徹底揹包 一個物品無限使用因此咱們只須要能使用就使用便可不須要管數量。blog

多重揹包 咱們把狀態轉移寫出來 其實第一次我是這樣作的 把多重揹包換成01揹包的模型而後複雜度 nmci 很是之高,可是換成一個更先進的狀態轉移。繼承

發現每一段都是連續的轉移 求某個區間的最大值 直接單調隊列就優化了。二進制拆分很久沒用了 其實就是分紅logn個 而後01揹包的選取便可,根據二進制的拆分因此正確性是顯然的。隊列

這裏有一個比較 有創造性的題目。ci

一眼 多重揹包單調隊列優化 可是其實咱們發現問題的本質是 求某個區間是否有一個1 這樣也能夠進行前綴和的優化。get

可是皆因常數有點大T掉了。再次考慮優化 咱們發現 只是求 一段區間中離咱們當前值最近的一個1便可。date

雖然可能較遠的1也可使用可是 從貪心角度來看 取最近的1給後面帶來的決策更優 因而咱們把倒着的過程優化到了正着的過程。

因而 根據貪心的最優性咱們成把兩倍常數卡到了一倍常數經過了此題。

分組揹包?怎麼作?一組中只能選取一個 更實際一點的是 對於一個j來講 咱們只會選擇一個物品 因爲是01揹包 那麼倒着選 而後內層循環 循環物品便可。

多人揹包?揹包的第k優解 怎麼辦?設狀態 f[i][j] 表示 對於容量爲 i 的第j優解 考慮轉移 這裏考慮刷表法 而後 轉移到 某某狀態 發現了麼 對於同一個i來講 j增大的時候 f數組單調不增 因此 能夠直接歸併的完成這個過程。

考慮一些難一些的dp 如 須要優化狀態 優化空間 優化轉移 ...其中我認爲優化狀態是最難的 我 基本上就是一個狀態想半天 而題解中的狀態卻設計的 很是的精巧。

接下來討論一道 對dp的深入理解的題目。

LINK:the heart of the tree 一句話題意 Q次詢問每次詢問某個點爲根的子樹內的重心。

關於重心有一些比較好的性質 可是 個人點分樹學藝不精 因此 知道的很少。

n 和 Q的數量級都到達了 3e5的數量級 暴力顯然不行。咱們至少要再logn的時間內求出答案 我曾想過線段樹維護dfs序而後進行區間的操做。發現不太行

考慮 一遍dfs序求出全部點的重心 從子樹往上走必然的結果是 此時的重心必定不會往裏面跳必定會往上面跳因此 考慮全部的重心向上跳的數量級是O(n)的 直接向上跳便可。

題解中海油 更 有趣的思路是 抱歉沒有了我以爲並不優秀。核心思想都差很少。

數位dp 這種dp省選之中常常出現 我沒有過人的天賦 我也沒有出衆的才能只能利用本身的 頭硬寫..

首先是 狀態要合適 而後是 狀態數量要在可控範圍內 轉移的時候要注意一些細節 如最高位的限制 及 前導0是否存在。

此時轉移 無非就是枚舉決策 當前數位填什麼qwq... 烏拉前導0 也是能夠放到狀態之中的和普通的狀態不同 值得注意的是

前導0的狀況有9*(n-1)種 其中n是數位的個數 其實這個放不放到狀態中都是無所謂的了 若是以爲很差寫那就放到狀態中 狀態中若是沒有親自開設一個位置給前導0的一系列狀態的話也不能強行放到f數組中。

具體的dp細節就是這樣了。關鍵是  狀態 狀態的數量 及 轉移的 細節。

值得一提的是 進行記憶化搜索的retunrn 時注意判斷limt的限制是否存在(若是存在天然不能return 我忽略了這一點在不經意間qwq。

update : 數位dp 統計一個區間以內的 符合某種特色的 數字個數 具備多種特色的時候考慮拆分 一個一個求。

這裏我以爲有兩個相似於類似但不相同的 問題。

1:給出一個區間求這個區間中 1-9 分別出現了多少次。

2:給出一個區間求這個區間中每一個數字的數位和?

轉換模型 2問題是1問題的子集。$ans2=\sum_{i=1}^{9} ans[i]*i;$

其中 1問題我在求解的時候很是之迷.2問題反而好求一點但複雜度較高

以此我分類討論 來闡明 數位dp的本質. 數位dp的本質和狀態dp的本質同樣 狀態合併 大大下降複雜度。

考慮第二個問題 如何 解決 考慮 每一個數字 的數位之和 是很小的數字 咱們將這相同的狀態進行合併 而後數位dp便可。

每次f數組表示在某某狀況下的 目標和是i的方案數便可。

考慮第一個問題 把問題拉向另外一個方向 發現一個數字出現的是1 ~ 9 纔對答案有貢獻 求某個區間中某個數字出現了多少次 這個顯然 也是求某一類有特色的數字 並不是多類 也沒有限制當前數字要有多少個

因此 從這一方面考慮狀態數量從本來的 位數*9 變到了 9 大大下降了複雜度.

兩種方法都經過此題 且 第一種方法比第二種方法不知道快到哪裏去了qwq

相關文章
相關標籤/搜索