对数位dp的一些拙见
這不是一篇介紹數位dpdpdp的文章,只是我思考后的一些記錄,怕以后就忘記了。
由于博主太菜不會組合數學,以下數位dpdpdp均采用記憶化搜索的方式。
首先最重要的就是狀態設計了,正常來說數位dpdpdp的狀態設計需要包含數的結構和狀態。
數位dpdpdp的復雜度可以簡單理解為開的數組的大小。
對于數位dpdpdp有兩種理解:
第一種: dpdpdp的狀態只與當前數的位數以及要維護的狀態有關。在這種理解方式下,dpdpdp狀態設計通常為f[pos][state]f[pos][state]f[pos][state],由于狀態中并未規定上下界,所以對于每次查詢操作,并不需要將其dpdpdp數組清成?1-1?1,這樣在應對多組查詢的時候可能會快一點。在記憶化的時候需要加上flag1...flag1...flag1...等限制上界的變量是否為111,即當前位是否可以選任意數,在多組測試情況下這個方法跑的還可以。當然這個只跑的快只能在維護一個數的時候跑的快,如果你要維護一對數,那么記憶化的時候flag1&&flag2flag1 \And\And flag2flag1&&flag2才能記憶化,這樣的話就會慢很多,導致TLETLETLE,所以當維護兩個數及以上的時候最好不要用這種記憶化方式。
寫成的代碼大概是這樣的:
第二種: 在狀態中加入0/10/10/1表示是否達到上界,即上文中的flag1,flag2...flag1,flag2...flag1,flag2...,這樣的話由于每次詢問的數都不同,所以每次都需要將fff數組置為?1-1?1才能記憶化,這樣的優點和缺點相比于上面的方式很明顯,優點就是這個狀態設計能記錄f[pos][state][0]f[pos][state][0]f[pos][state][0]的信息,即如果當前位不能自由選也可以記憶化,而上面的只能記錄下來f[pos][state][1]f[pos][state][1]f[pos][state][1]的信息,只不過我們將最后一維省略了。缺點也比較明顯,每次都需要初始化fff數組,讓后重新dpdpdp一次,不過也不會太慢。
寫成代碼大概是這樣的:
對于前導零:
當涉及到對數的結構特點進行維護的時候就有可能需要維護一個前導零了。比如說求[l,r][l,r][l,r]內有多少個數的位數中含kkk個000,這個時候如果不維護一個前導零的話會將如001000100010中前面兩個000也算入答案,這顯然是不正確的。
數位dpdpdp很多題目求貢獻的話都是按位或者按照數來求的。
做過的例題:
2020 ICPC 上海 Sum of Log 數位dp + 優化狀態
hdu 6899 Xor 數位dp
FZU - 2042 The Mad Mathematician 數位dp + 算貢獻
暫時先更這些,后面有更好的理解會補充。
總結
以上是生活随笔為你收集整理的对数位dp的一些拙见的全部內容,希望文章能夠幫你解決所遇到的問題。