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