數字DP小結 記憶化搜尋版

2021-07-04 03:37:16 字數 1822 閱讀 1665

之前寫數字dp是用dp方程遞推形式寫,接觸記憶化搜尋版後,發現使用dfs更加清晰明了,思路很順,**簡潔的多w。

首先上模板,以hdu 2089 不要62為例

#define _crt_secure_no_deprecate

#include #include #include #include #include #include #include #include #include #include using namespace std;

#define pow(i) (1<<(i))

#define inf (1<<29)

#define mem(x) memset(x,0,sizeof(x))

#define mem1(x) memset(x,-1,sizeof(x))

typedef long long ll;

int dp[10][2];

int digit[20];

int dfs(int pos,bool state,bool fp)//pos為當前位數,state為當前狀態[1],fp為上一位是否到達上限的標誌

if(!fp) //若前一位不是上限,即這一位可以到最大,則更新dp值[5]

dp[pos][state]=ret;

return ret; //返回ret

}int cal(int x)

return dfs(len,0,1);

}int main()

return 0;

}

幾點解釋:

[1]:此題中state表示上一位是否為6.可根據不同問題更改state。

[2]:此處return的結果根據題目而定。此題到最後一位一定符合條件,因此return1。其他題目可根據引數來進行判斷此時是否符合條件。

[3]:fp為first plcae。即之前位是否達到上限。即:若cal(4213),若第一位為4,第二位最多列舉到2,此時fp=1,digit為2。若第一位為3.第二位則可列舉到9,此時fp=1。

[4]:此處的判定條件根據題目不同而更改。state本題表示上一位是否為6,因此若此時列舉的i為6,state=1。fp的判定每題一致,若之前位到達上限,且這一位也為上限,則fp為1。

[5]:dp[i][j]表示i位,j狀態所有取值滿足條件的個數。顯然若fp==1,不滿足所有取值,因此不可更新dp值

做題套路:

1.定義dp陣列。dp的維數依題意和dfs記錄的狀態而定。第一維為pos,為當前列舉的位數。其他維是當前取值的狀態。

2.初始化。dp初始化為-1。有時題目需要初始化其他陣列,如每一位的權值。cf 55 d題中,dp的一維儲存lcm值,數值很大,為使得陣列開的下,需要預先初始化並且離散化。

3.計算左右界l~r。最終答案一般為cal(r)-cal(l-1)。

4.cal陣列內預處理每一位的上限值,記錄在digit陣列中。返回dfs值

5.進行dfs。

dfs引數設定:

1.若為連續2位不能出現的數字,可用state記錄前一位是否出現過。如hdu 2089,hdu 3555

2.若題目要求各位和/數字的值滿足某個條件,可用sum/pre記錄。注意取模。如cf 55d,hdu 3652,hdu 3709,hdu 4722等

3.若題目要求記錄每一位的數字狀態的總數,可用n進製表示。如spoj 10606,用三進製的表示每個數字的狀態。

列舉上限的選取:

為digit[pos]:n。n為當前數的進製。一般為十進位制,n為9。個別題目例外。如poj 3252,要求各位1的個數和0的個數,那麼在處理時按二進位制處理每一位。

最後,記得用ll ,記得用ll, 記得用ll 。重要的事要說三遍tut

codeforces (數字dp 記憶化搜尋)

題意 列舉 a,b 之間的beautiful數 即這個數所有位上的數都能整除這個數 思路 用pos記錄位置 num記錄當前位置前面所有位組成的數 當時開不了這麼大的陣列 有知道1 9 的最小公倍數是2520 所以num記錄 上文的num 2520 就可以了 現在就剩下記錄當前位置前面各位都出現過0 ...

數字DP的記憶化搜尋形式

數字dp的記憶化搜尋形式比一般遞推形式好寫多了,而且一般不容易出錯。dfs求 0,n 有多少個符合的,先把n換成字串形式。cur 現在處理到哪一位。s 搜尋到目前為止,之前的狀態,具體什麼狀態看情況而定。e 是否到達邊界,如果沒到這一位只取到9,否則只能取到bit cur z 前導0標記,也就是是否...

記憶化搜尋 dp

例子 33 1132 3411 1先去找 1,1 的最長距離,很明顯為1 接著找 1,2 的最長距離,很明顯為1 接著找 1,3 的最長距離,為2 1,3 1 2 然後找 2,1 的最長距離,為2 2,1 1 1 然後是 2,2 的最長距離,如果沒有記憶化,那麼搜尋過程為 2,2 2 1 1 1 但...