如果考虑成为数位dp的话,应该怎么做呢?
dfs(数位,数位和,状态,是否为阈值);
很明显,dfs是这样的,但是会发现,这样的状态记录会是很大的,无法用数组记录,此时,我们不妨枚举数位和,又有数位和==模值,最后的状态应该为0、且数位和==模值。所以dp方程显而易见。
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <string> 5 #include <cstring> 6 #include <algorithm> 7 #include <limits> 8 #include <vector> 9 #include <stack> 10 #include <queue> 11 #include <set> 12 #include <map> 13 #include <bitset> 14 #include <unordered_map> 15 #include <unordered_set> 16 #define lowbit(x) ( x&(-x) ) 17 #define pi 3.141592653589793 18 #define e 2.718281828459045 19 #define INF 0x3f3f3f3f 20 #define HalF (l + r)>>1 21 #define lsn rt<<1 22 #define rsn rt<<1|1 23 #define Lson lsn, l, mid 24 #define Rson rsn, mid+1, r 25 #define QL Lson, ql, qr 26 #define QR Rson, ql, qr 27 #define myself rt, l, r 28 #define pii pair<int, int> 29 #define MP(a, b) make_pair(a, b) 30 using namespace std; 31 typedef unsigned long long ull; 32 typedef unsigned int uit; 33 typedef long long ll; 34 ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; } 35 const int maxN = 180; 36 ll A, B; 37 int dig[21]; 38 ll mod; 39 ll dp[21][maxN][maxN]; 40 ll dfs(int pos, int sum, int state, bool top) 41 { 42 if(sum > mod) return 0; 43 if(pos <= 1) 44 { 45 if(sum == mod && !state) return 1; 46 else return 0; 47 } 48 if(!top && (~dp[pos][sum][state])) return dp[pos][sum][state]; 49 ll ans = 0; 50 int u = top ? dig[pos - 1] : 9; 51 for(int i = 0; i <= u; i ++) 52 { 53 ans += dfs(pos - 1, sum + i, (state * 10 + i) % mod, top && (i == u)); 54 } 55 if(!top) dp[pos][sum][state] = ans; 56 return ans; 57 } 58 ll solve(ll x) 59 { 60 ll ans = 0; 61 for(int i = 1; i <= 20; i ++) 62 { 63 dig[i] = x % 10; 64 x /= 10; 65 } 66 for(int i = 1; i < maxN; i ++) 67 { 68 mod = i; 69 memset(dp, -1, sizeof(dp)); 70 ans += dfs(20, 0, 0, true); 71 } 72 return ans; 73 } 74 int main() 75 { 76 scanf("%lld%lld", &A, &B); A--; 77 printf("%lld\n", solve(B) - solve(A)); 78 return 0; 79 }