桁DP入門
Shunsuke Otani
桁DPとは
 N以下の整数で○○の条件を満たす数の個数
 N以下の整数で○○の条件を満たす数の最大値
などの問題で使える桁ごとに分けて考える動的計画法
例題1
 Q:100未満の整数で3がつく数の個数は?
int型→string型で
数字に3がつくか
全探索?
10ごとに3がつく数は
1増えていそうだから
N/10?
O(N)では間に合わない
ことも…
桁DPの考え方(1の桁に3がつく)
10 1
0
3を含む
3を含まない
1の桁10の桁
全部
10×1 = 10
10の桁の数字
※箱には○桁目まで見た時の答えが入ります
桁DPの考え方(1の桁に3がつかない)
9 0
81 9
3を含む
3を含まない
1の桁10の桁
3以外
9 × (10 - 1) = 81
10の桁の数字
9 × 1 = 9
※箱には○桁目まで見た時の答えが入ります
桁DPの考え方(結果を足す)
19 1
81 9
3を含む
3を含まない
1の桁10の桁
100未満(~99)の範囲を求めるため、10の桁まで考えればよい
※箱には○桁目まで見た時の答えが入ります
つまり
先ほどの遷移 + 条件 = 桁DP
条件!???
例題だと…
 N < 100
 この条件を先ほどの遷移に加えたい…
例題2
 Q:55以下の整数で3がつく数の個数は?
例題2(1の桁に3がつく)
53を含む
3を含まない
1の桁10の桁
0
1
0
N < 50 N >= 50 && N <= 55
1×5(0,1,2,3,4)
1
1の桁10の桁
0
1
0
1×1(5)
3を含む
3を含まない
例題2(1の桁に3がつかない)
93を含む
3を含まない
1の桁10の桁
36
0
9
N < 50 N >= 50 && N <= 55
9×4(0,1,2,4)
0
1の桁10の桁
5
0
5
5×1(5)
3を含む
3を含まない
9×1(3)
例題2(結果)
143を含む
3を含まない
1の桁10の桁
36
1
9
N < 50 N >= 50 && N <= 55
1
1の桁10の桁
5
1
5
3を含む
3を含まない
よって答えは 14 + 1 = 15
しかし…
 2桁までの遷移は簡単にプログラムで実装できる
 Nが3桁以上になった場合は…?
N <= 255のとき
 下の桁から見る場合
 1. (0~5),(0~9)それぞれの3の個数をカウント
 2. (0~55),(0~99)1を使い、それぞれの3の個数をカウント
 3. (0~255)2を使い、3の個数をカウント
 もう少し簡単なアルゴリズムはないのか…
 上の桁から見てみよう!
例題2(10の桁に3がつく)
13を含む
3を含まない
1の桁10の桁
0
10
0
N < 50 N >= 50 && N <= 55
1×10(0~9)
0
1の桁10の桁
0
0
0
0×6(0~5)
3を含む
3を含まない
例題2(10の桁に3がつかない)
03を含む
3を含まない
1の桁10の桁
4
4
36
N < 50 N >= 50 && N <= 55
4×9(0~2,4~9)
0
1の桁10の桁
1
1
5
1×5(0,1,2,4,5)
3を含む
3を含まない
4×1(3) 1×1(3)
例題2(結果)
13を含む
3を含まない
1の桁10の桁
4
14
36
N < 50 N >= 50 && N <= 55
0
1の桁10の桁
1
1
5
3を含む
3を含まない
よって答えは 14 + 1 = 15
上の桁から見てみよう
 前頁と同条件(N<=255)で上の桁から見たとき
 1. (0~1),(2)の3の個数をカウント
 2. (0~24),(25)1を使い、それぞれの3の個数をカウント
 3. (0~254),(255)2を使い、それぞれの3の個数をカウント
 見る順番を変えるだけで考えやすくなった!
これをどうやって実装すれば…
未満Flagを導入
Nの制約がない場合の遷移
 dp[digit(N)][2] (dp[桁数][3の有無])
未満Flagを導入
 dp[digit(N)][2][2] (dp[桁数][3の有無][N未満])
 dp[i][*][0]には N未満となる数についての答え
 dp[i][*][1]には i桁目までNと同じ数についての答え
未満Flagの具体例
*先ほどのdpから3の有無を除いて考える
 N = 12345
 dp[3][1]:123○○未満となる数(0~12299)
つまり(0~122)の範囲の3がつく数の個数
 dp[3][0]:123○○となる数(12300~12345)
つまり(123)の3がつく数の個数
遷移を見てみる
*先ほどのdpから3の有無を除いて考える
N = 12345
 dp[3][0](123○○)→dp[4][*]の遷移は…
 dp[4][0]への遷移は(123○○)→(1234○)より
dp[4][0]= dp[3][0]
 dp[4][1]への遷移は(123○○)→(123(0~3)○)より
dp[4][1]= dp[3][0]×4(0~3の個数)
簡単な問題から
 1~Nの整数の個数を桁DPで求めてみよう
 まずはdpテーブルを考えてみよう!
DPテーブルは…
 dp[digit(N)][smaller(未満Flag)]
解法例
演習タイム
1. 0からNまでの整数で3が含まれる数の個数を桁dpで求めてみよう!
2. 0からNまでの整数で桁の和が3の倍数な数の個数を桁dpで求めてみよう!
ご清聴ありがとうございました

桁DP入門