-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
重构
- Loading branch information
Showing
1 changed file
with
34 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,41 @@ | ||
# 数位DP | ||
从高位往低位,枚举每一位选什么,记忆化搜索,搜索需要参数记录前缀相关的信息 | ||
从高位往低位,枚举每一位选什么,记忆化搜索,搜索时需要参数记录高位相关的信息 | ||
|
||
只记忆化不贴着上界没有前导0的情况 | ||
对于limit,要看情况选择是否记忆化,如果limit=1的状态数远小于limit=0的状态数,那就只记忆化limit=0的状态 | ||
|
||
区间 [l,r] 统计合法数个数的,通常用前缀和思想,即 ans[1,r]-ans[1,l-1] | ||
## 前缀相关信息 | ||
区间限制:高位选择是否贴着区间上限,如果不贴着,该位可以随便选,否则不能超过区间上限 | ||
## 常见参数 | ||
pos: int,表示当前枚举的位置,一般从高到低 | ||
|
||
前导0:当该位及高位都是0,那么该位是前导0,如果统计的是digit,不计入答案 | ||
limit: bool,表示枚举的第 pos 位是否受到限制(上限或下限) | ||
|
||
hdu2089不要62:上一位选的什么 | ||
last: int,表示上一位填写的值 | ||
|
||
洛谷P2602:当前要计算的数字,在高位选择了多少个 | ||
lead0: bool,表示是否有前导零 | ||
|
||
sum: int,表示高位的数位和 | ||
|
||
rem: int,表示高位取模的余数 | ||
|
||
st: int,表示高位的一些信息(状态压缩) | ||
```cpp | ||
ll dp[MAXD][...]; | ||
ll dfs(int pos, ..., int limit) | ||
{ | ||
if (!pos) | ||
return ...; | ||
ll &d = dp[pos][...]; | ||
if (!limit && d != -1) return d; | ||
ll ans = 0; | ||
for (int v = (limit ? A[pos] : 9); v >=0 ; --v) | ||
ans += dfs(pos - 1, ..., limit && A[pos] == v); | ||
if (!limit) d = ans; | ||
return ans; | ||
} | ||
ll f(ll x) | ||
{ | ||
int len = 0; | ||
while (x) A[++len] = x % 10, x /= 10; | ||
return dfs(len, ..., true); | ||
} | ||
``` |