HDU 4389 X mod f(x) [数位DP]

  求区间内该数的值模该数的各位数字和为0的数有多少个。

  没想到简洁的状态,d[i][s][mod][r]表示i位,前缀和为s,总和为mod,%mod=r的数有多少个。

  

 1 #include <string.h>
 2 #include <stdio.h>
 3 #include <algorithm>
 4 //i位,前缀和为s,总和为mod,%mod=r的数有多少个
 5 int num[10], len, ans, sum, d[10][82][82][82];
 6 int dfs(int i, int s, int mod, int r, bool e){
 7     if(mod > 81 || s > mod) return 0;
 8     if (i == -1) return s == mod && r == 0;
 9     if (!e && d[i][s][mod][r]) return d[i][s][mod][r];
10     int u = e?num[i]:9, res = 0;
11     for (int x = 0; x <= u; ++x){
12         res += dfs(i-1, s+x, mod, (r*10+x)%mod, e&&x==u);
13     }
14     return e?res:d[i][s][mod][r] = res;
15 }
16 int get(int x) {
17     ans = 0;
18     for (len = sum = 0; x; num[len++] = x%10, sum += x%10, x/=10);
19     for (int i = 1; i <= len * 9; i++) ans += dfs(len-1, 0, i, 0, 1);
20     return ans;
21 }
22 int cas, a , b;
23 int main(){
24     //freopen("test.in", "r", stdin);
25     memset(d, -1, sizeof d);
26     scanf("%d", &cas);
27     for (int ca = 1; ca <= cas; ca++){
28         scanf("%d%d", &a, &b);
29         printf("Case %d: %d\n", ca, get(b) - get(a-1));
30     }
31     return 0;
32 }
原文地址:https://www.cnblogs.com/swm8023/p/2711529.html