學習筆記 訓練記錄 數字DP

2022-05-20 09:28:17 字數 2032 閱讀 5354

數字dp,即對數字進行拆分,利用數字來轉移的一種dp,一般採用記憶化搜尋,或者是先預處理再進行轉移

乙個比較大略的思想就是可以對於給定的大數,進行按數字進行固定來轉移記錄答案

區間型別的,可以考慮字首和的思想,求[l,r]可以看做求[1,r]-[1,l)

其實還有一種,是按照二進位制建一顆0,1樹來表示,來做,但是比並沒有做過,以後再總結

hdu-2089

題目大意:對於區間[l,r]求有多少不包含'62'且不包含'4'的數,題目允許有前導零

思路:

數字dp,考慮f[i][j]表示位數為i,最高位為j的滿足的個數

預處理後,統計答案即可,統計答案大致就是固定每一位,進行統計

code:

#include#include

#include

#include

#include

using

namespace

std;

intread()

while (ch>='

0' && ch<='

9')

return x*f;

}int

n,m;

int f[10][10

];void

prework()

int calc(int

x),len=0,ans=0

;

while (x!=0)

for (int i=len; i>=1; i--)

return

ans;

}int

main()

return0;

}

hdu-3652

題目大意:給定n,求到n中,包含'13'且被13整除的數的個數

思路:

設計狀態f[i][j][k][0/1]表示位數為i,最高位為j的%13餘k的數字包含和不包含13的個數

那麼同樣預處理,這裡不含前導零,需要額外做乙個值去進行計算,計算到n以內的,計算n+1即可

code:

#include#include

#include

#include

#include

using

namespace

std;

long

long

n;long

long f[20][20][15][2

];long

long cf(int x,int

y)void

prework()

}//for (int i=1; i<=10; i++)

//for (int j=0; j<=9; j++)

//for (int k=0; k<13; k++)

//printf("%i64d %i64d\n",f[i][j][k][1],f[i][j][k][0]);

}long

long calc(long

long

x),len=0,f=0; long

long ans=0

;

while (x)

for (int i=0; i<=digit[len]-1; i++)

ans+=f[len][i][0][0

];

long

long tmp=cf(digit[len],len-1

);

for (int tt,i=len-1; i>=1; i--)

if (digit[i]==3 && digit[i+1]==1) f=1

; tmp+=cf(digit[i],i-1

); }

return

ans;

}int

main()

HDU訓練記錄2 基礎數字dp

題目描述 傳送門題意 求0 n中含 49 的數的個數。題解狀態 f i j 表示i位數所有以j開頭的數中合法 不含 49 的數的個數。轉移 if j 4 k 9 f i j f i 1 k 列舉jk分別為i和i 1位數的開頭並且滿足條件。求解時用總數減去dp值。注意 這道題傳m 1的話有可能爆lon...

數字dp學習筆記

我們通常使用字首和的思想和記憶化搜尋來實現數字 dp。就是上面所說的常見問法。例題 windy 數 int dfs int k,int x,int p,int q if p q f k x res return res 這道題的難點就在於對相鄰兩個數字之差至少為 2 的處理,我們一開始將 x 設為 ...

DP專題 學習筆記 數字 DP

目錄3.練習題 update 2021 2 23 最近作者發現數字 dp 的 f 陣列初始化有問題,導致 出現了根本性錯誤 原理不變 現在已經糾正,對各位讀者造成的困擾深表歉意。數字 dp,是一種 dp 廢話 專門用於數字統計類問題。這種問題首次接觸可能會有些難理解,但是練過幾道題之後就會掌握套路了...