**自
數字dp
•在給定區間
[a,b]
內,找滿足要求的數。 •
要求一般和數大小無關,而與數的組成有關 •
例如,遞增的,
1234,2579… •
雙峰的,
19280,26193… •
含49的,
49, 149, 1492… •
整除13的,
26, 39… •
麻煩在於,規模大,位數
>100
,不能列舉。 •
區間往往不是整百整千,邊界問題 •
注意 – 記憶化搜尋思路清晰 –
開適當空間(能省則省) –
尋找合適的狀態,簡化計算量
例
hdu3886
•
題目大意:給一定區間
[a,b]
,一串由
/,\,-
組成的符號串。求滿足符號串的數字個數。 •
/表示數字從左到右遞增 •
\表示數字從左到右遞減 •
-表示數字從左到右相等 •
例如: •
/-\ •
1221,123455543 •
資料規模:
• a,b<=10^100
分析
f(a,b) = f(b,0)-f(a-1,0) 暴力
+儲存
= 記憶化搜尋 •
暴力: •
暴力列舉每一位
(0..9),
注意區間邊界
;與符號的匹配。 •
dfs(i,j,k,flag)
• 列舉第
i位的數,匹配
str[j],
前一位是
k,是否達到上限
(flag=
true,false)
• 達到了上限則只能列舉
0..num[i]
,否則可以列舉
0..9 •
儲存 • dfs
(i,j,k,flag)
• 設狀態與遞迴引數一致f[i
][j][k][flag]
,表示當列舉到第
i位的數,匹配
str[j],
前一位是
k,是否達到上限
(flag=
true,false
)時,滿足要求的數字個數。 •
dfs的過程,相當於在填充f,
f的空間
o(100*10*10*2)
,則dfs
的時間o(20000)
實現
• 1.
空間優化,只需記錄
flag=false
時的值。因為
flag=true
的值只會計算一次,不是冗餘計算,不用記錄。 –
(不一定要開和引數一樣的陣列,適當變換下,分成幾種情況開多個陣列,可以節省下記憶體) •
2.前導
0不算數,不能和符號串匹配。 –
如,-/,0003(x),0113 •
3.1234
匹配//
,會被算成倆個 •
4. 個位放在
f[0][…]
,且只記錄
flag=false
的值時,f與數
a,b無關!可以反覆利用
其他型別
• 整除13
• dfs(i
, m,flag) •
列舉第i位數,前面列舉出的數模
13的餘數
m,是否到達上限
flag •
整除自身各位數
cf55d •
dfs(i
, m,l, flag) •
列舉第i位數,前面列舉出的數模
lcm(0..9)
,lcm(
前面列舉出的數
),是否達到上限 •
包含」49」 •
dfs(i
, k,find, flag) •
列舉第i位數,前一位是
k,是否已包含
」49」(find)
,是否達到上限 •
分類討論:
前一位是否為
4,當前是否已包含「49」
部分解題報告:(習慣寫在**末尾...)
poj 3252 round number
hdu 3709 balanced number
hdu 3652 b-number
codeforce 55d beautiful numbers
數字DP 按位DP
之前說過要做個專題,雖然隔了好長時間。但說話還是算數的,把之前做的ppt翻出來貼上,好吧,我就是懶。見識的還是少,歡迎討論啊 數字dp 在給定區間 a,b 內,找滿足要求的數。要求一般和數大小無關,而與數的組成有關 例如,遞增的,1234,2579 雙峰的,19280,26193 含49的,49,1...
數字DP專題
hdu 2089 不要62 hdu 3555不能出現連續的49 uestc 1307相鄰的數差大於等於2 hdu 3652 出現13,而且能被13整除。hdu 3709平衡數 light oj 1140兩個數之間的所有數中零的個數。lightoj 1032 二進位制數中連續兩個 1 出現次數的和 c...
牛客網dp專題 數字dp
題目 輸入a和b,求a到b的所有數之中有多少0出現 題解 先算個位,個位是0的情況有x種 再算十位,十位是0的情況有y種 一共是x y 用數字dp做 dp i 中存的是從0 99 9 共i個9 中0的個數 不含前導0 dp0 i 中存放的是00 0 99 9 共i個0,i個9 中0的個數 含前導0 ...