Skip to content

Commit b305b6d

Browse files
author
Takanori MAEHARA
authored
General DigitDP
1 parent d454c58 commit b305b6d

1 file changed

Lines changed: 51 additions & 1 deletion

File tree

dynamic_programming/digit_dp.cc

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,17 @@ string toString(T x) {
107107
return ss.str();
108108
}
109109

110+
//
111+
// Sum of digits.
112+
// Since sum is not distributive, (u + v) + d != (u + d + v + d),
113+
// we need to augment the number to contain the number of numbers.
114+
// Let + and * be defined by
115+
// (u,a) + (v,b) = (u+v,a+b),
116+
// (u,a) * d = (u+a*d,a).
117+
// Then, they are right-distributive as
118+
// ((u,a) + (v,b)) * c = (u+v,a+b) * c = (u+v+ac+bc,a+b),
119+
// (u,a) * c + (v,b) * c = (u+ac,a) + (v+bc,b) = (u+v+ac+bc,a+b).
120+
//
110121
using Int = long long;
111122
Int sumOfDigits(string z, bool eq = true) {
112123
struct Value {
@@ -160,6 +171,13 @@ Automaton intersectionAutomaton(Automaton1 A, Automaton2 B) {
160171
return M;
161172
}
162173

174+
//
175+
// Count the zigzag numbers that is a multiple of M.
176+
// Here, a number is zigzag if its digits are alternatively
177+
// increasing and decreasing, like 14283415...
178+
// Since there are multiple conditions, we use automaton
179+
// composition to simplify the approach.
180+
//
163181
void AOJ_ZIGZAG() {
164182
char A[1000], B[1000];
165183
int M;
@@ -219,7 +237,39 @@ void AOJ_ZIGZAG() {
219237
cout << (b + (10000 - a)) % 10000 << endl;
220238
}
221239

240+
//
241+
// Count the numbers that does not contain 4 and 7 in each digit.
242+
//
243+
void ABC007D() {
244+
string a, b;
245+
cin >> a >> b;
246+
247+
struct ForbiddenNumber {
248+
int init = 0;
249+
int size() { return 2; }
250+
int next(int state, int a) {
251+
if (state == 1) return 1;
252+
if (a == 4 || a == 9) return 1;
253+
return 0;
254+
}
255+
bool accept(int state) { return state == 1; }
256+
};
257+
struct Counter {
258+
long long value = 0;
259+
Counter &operator+=(Counter x) {
260+
value += x.value;
261+
return *this;
262+
}
263+
Counter &operator*=(int d) {
264+
return *this;
265+
}
266+
};
267+
cout << digitDP(b, (Counter){1}, ForbiddenNumber(), true).value
268+
- digitDP(a, (Counter){1}, ForbiddenNumber(), false).value << endl;
269+
}
270+
222271
int main() {
272+
ABC007D();
223273
//SPOJ_CPCRC1C();
224-
AOJ_ZIGZAG();
274+
//AOJ_ZIGZAG();
225275
}

0 commit comments

Comments
 (0)