-
Notifications
You must be signed in to change notification settings - Fork 77
/
Copy pathDigit_dp_I.cpp
52 lines (47 loc) · 1.15 KB
/
Digit_dp_I.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// Digit DP
// Count how many numbers are there between A and B inclusive which sum of digits is equal to S
#define BIT_LENGTH_32 32
#define BIT_LENGTH_64 64
#define MAX_SUM 200
i64 dp[BIT_LENGTH_64][MAX_SUM];
bool visited[BIT_LENGTH_64][MAX_SUM];
i64 A, B;
int S;
i64 solveUtil(int depth, int sum) {
if(depth == 0) {
return (i64) (sum == 0);
}
if(visited[depth][sum]) {
return dp[depth][sum];
}
i64 ret = 0LL;
for(int d = 0; d <= 9; ++d) {
if(sum - d >= 0) {
ret += solveUtil(depth - 1, sum - d);
}
}
visited[depth][sum] = true;
return dp[depth][sum] = ret;
}
i64 solve(i64 N) {
if(N < 0LL) return 0LL;
char buffer[BIT_LENGTH_64];
sprintf(buffer, LLD, N);
int len = strlen(buffer);
int sum = S;
int depth = len;
i64 ret = 0LL;
for(int i = 0; i < len; ++i) {
int digit = buffer[i] - '0';
for(int d = 0; d < digit; ++d) {
if(sum - d >= 0) {
ret += solveUtil(depth - 1, sum - d);
}
}
depth--;
sum -= digit;
}
ret += (sum == 0);
return ret;
}
// solve(B) - solve(A - 1LL);