Reference: http://www.cppblog.com/Yuan/archive/2013/03/09/139299.html#198320
In this way, a process is that the Pre * 10 ^ POS + next sub-statements are determined, and next is a variable.
Therefore, the parameter is pre, POS is added with some others, and there is a mark doing, indicating whether the calculation has an upper limit or no upper limit (in all cases, that is, end = 9)
DFS (pos-1, npre, doing & I = end)
Balance, that is, sigma A [I] * (I-o) = 0 o is the fulcrum
For a number, pivot o is unique, so there is no repeated count (but there is a special case, that is, 0, 00, 000, etc. are the same, accounting is calculated multiple times,
The last part is subtracted)
Assuming that the POS is checked, for the formula Σ A [I] * (I-o) = 0 above, the pivot point is determined as O
The result of the previous number of sigma A [I] * (I-o) is pre
Therefore, the parameter must be POs, O, pre
Return pre = 0 when Pos =-1 is detected
Otherwise, check whether the current condition is calculated or the actual situation (doing 1 indicates all cases, 0 indicates special circumstances, that is, there is a location restricted)
For all cases and the Dp value! =-1, direct return
Otherwise, 0 to end will be enumerated.
Pivot o needs to be enumerated in the outermost layer.
Memory search: write in this way. A process is that the Pre * 10 ^ POS + next sub-statements are determined, and next is a variable.
Therefore, the parameter is pre, POS is added with some others, and there is a mark doing, indicating whether the calculation has an upper limit or no upper limit (in all cases, that is, end = 9)
DFS (pos-1, npre,
Doing & I = end)
Zju AC code:
# Include <cstdio> # include <cstring> # include <algorithm> using namespace STD; long DP [19] [19] [2000]; int digit [19]; long long DFS (INT POs, int o, int pre, bool doing) {If (Pos =-1) return pre = 0; // POS is equal to-1, indicating that a single bit has been calculated. In this case, pre is its value. If (pre <0) return 0; // pruning if (! Doing & DP [POS] [O] [pre]! =-1) return DP [POS] [O] [pre]; long ans = 0; int end = doing? Digit [POS]: 9; For (INT I = 0; I <= end; I ++) {int npre = pre; npre + = (POS-O) * I; ans + = DFS (pos-1, O, npre, doing & I = END); // doing is false at the highest bit of each, resulting in its derivation being false} If (! Doing) DP [POS] [O] [pre] = ans; return ans;} long CAL (long x) {int Pos = 0; while (X) {digit [POS ++] = x % 10; X/= 10;} long ans = 0; For (int o = 0; O <Pos; O ++) {ans + = DFS (pos-1, O, 0, 1);} return ANS-(pos-1); // duplicate 0} int main () {int T; for (scanf ("% d", & T); t --;) {long left, right; memset (DP,-1, sizeof (DP )); scanf ("% LLD", & left, & right); printf ("% LLD \ n", Cal (right)-cal (left-1 ));} return 0 ;}
Submit on HDU for half a day, Wa for half a day, and check the boundary for half a day. In the end, change % LDD to % i64d !!! After the modification is complete, the AC is on the HDU and the Wa is started on zju ..
Hdu ac code:
# Include <cstdio> # include <cstring> # include <algorithm> using namespace STD; long DP [19] [19] [2000]; int digit [19]; long long DFS (INT POs, int o, int pre, bool doing) {If (Pos =-1) return pre = 0; // POS is equal to-1, indicating that a single bit has been calculated. In this case, pre is its value. If (pre <0) return 0; If (! Doing & DP [POS] [O] [pre]! =-1) return DP [POS] [O] [pre]; long ans = 0; int end = doing? Digit [POS]: 9; For (INT I = 0; I <= end; I ++) {int npre = pre; npre + = (POS-O) * I; ans + = DFS (pos-1, O, npre, doing & I = END); // doing is false at the highest bit of each, resulting in its derivation being false} If (! Doing) DP [POS] [O] [pre] = ans; return ans;} long CAL (long x) {int Pos = 0; while (X) {digit [POS ++] = x % 10; X/= 10;} long ans = 0; For (int o = 0; O <Pos; O ++) {ans + = DFS (pos-1, O, 0, 1);} return ANS-(pos-1); // duplicate 0} int main () {int T; for (scanf ("% d", & T); t --;) {memset (DP,-1, sizeof (DP); long left, right; scanf ("% i64d % i64d", & left, & right); printf ("% i64d \ n", Cal (right)-cal (left-1 ));} return 0 ;}