Skip to content

Commit d42ade3

Browse files
committed
Dynamic programming - number of substrings and subsequences of number string s divisible by k
1 parent 2ec52e8 commit d42ade3

File tree

3 files changed

+85
-0
lines changed

3 files changed

+85
-0
lines changed

algorithms/.DS_Store

0 Bytes
Binary file not shown.

algorithms/Digit_dp_III.cpp

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// calculates number of substrings divisble by d
2+
int solve(string const& num, int d) {
3+
int ans = 0;
4+
int n = (int)num.length();
5+
vector<vector<int>> dp(n, vector<int>(d, 0)); // dp[i][j] = number of substrings ended at i with remainder j (mod d)
6+
for(int i = 0; i < n; i++) {
7+
int digit = num[i] - '0';
8+
dp[i][digit % d]++;
9+
if(i > 0) {
10+
for(int j = 0; j < d; j++) {
11+
int r = (j * 10 + digit) % d;
12+
dp[i][r] += dp[i - 1][j];
13+
}
14+
}
15+
ans += dp[i][0];
16+
// if numbers with preceeding 0 aren't allowed except '0' itself
17+
/*
18+
if(digit == 0) {
19+
dp[i][digit % d]--;
20+
}
21+
*/
22+
}
23+
return ans;
24+
}
25+
26+
/*
27+
solve("10888", 8) => 12
28+
*/

algorithms/Digit_dp_IV.cpp

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// calculates number of subsequences divisble by d
2+
int solve(string const& num, int d) {
3+
int ans = 0;
4+
int n = (int)num.length();
5+
vector<vector<int>> dp(n, vector<int>(d, 0)); // dp[i][j] = number of subsequences ended at i with remainder j (mod d)
6+
for(int i = 0; i < n; i++) {
7+
int digit = num[i] - '0';
8+
dp[i][digit % d]++;
9+
for(int j = 0; j < i; j++) {
10+
for(int k = 0; k < d; k++) {
11+
int r = (k * 10 + digit) % d;
12+
dp[i][r] += dp[j][k];
13+
}
14+
}
15+
ans += dp[i][0];
16+
// if numbers with preceeding 0 aren't allowed except '0' itself
17+
/*
18+
if(digit == 0) {
19+
dp[i][digit % d]--;
20+
}
21+
*/
22+
}
23+
return ans;
24+
}
25+
26+
/*
27+
solve("10888", 8) => 20
28+
*/
29+
30+
31+
32+
// Top-down approach
33+
34+
int solveUtil(int indx, int mod, string const& num, int d, vector<vector<int>>& dp) {
35+
if(indx == (int)num.length()) {
36+
return (mod == 0);
37+
}
38+
if(dp[indx][mod] != -1) {
39+
return dp[indx][mod];
40+
}
41+
int ret = 0;
42+
int digit = num[indx] - '0';
43+
ret += solveUtil(indx + 1, (mod * 10 + digit) % d, num, d, dp);
44+
ret += solveUtil(indx + 1, mod, num, d, dp);
45+
46+
return dp[indx][mod] = ret;
47+
}
48+
49+
int solve(string const& num, int d) {
50+
int n = (int)num.length();
51+
vector<vector<int>> dp(n, vector<int>(d, -1));
52+
return solveUtil(0, 0, num, d, dp);
53+
}
54+
55+
/*
56+
solve("10888", 8) - 1 // minus 1 to exclude empty string counting
57+
*/

0 commit comments

Comments
 (0)