BZOJ 1799 - [AHOI2009]self 同类分布 - 枚举 数位DP
Description
找出$[L, R]$ 区间内有多少数, 各位数字和 能整除原数
Solution
枚举每个可能的数字和, 进行数位DP即可 , 水爆
Code
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define ll long long 5 using namespace std; 6 7 int tot = 162; 8 int a[20], mod; 9 ll sum[19][163][163]; 10 11 ll dfs(int pos, int ad, int r, bool lim, bool lead) { 12 if(ad > mod) 13 return 0; 14 if(!pos) return ad == mod && r == 0; 15 if(!lim && !lead && sum[pos][ad][r] != -1) 16 return sum[pos][ad][r]; 17 int up = lim ? a[pos] : 9; 18 ll tmp = 0; 19 for(int i = 0; i <= up; ++i) { 20 tmp += dfs(pos - 1, ad + i, (r * 10 + i) % mod, lim && a[pos] == i, lead && i == 0); 21 } 22 if(!lim && !lead) 23 sum[pos][ad][r] = tmp; 24 return tmp; 25 } 26 27 ll work(ll x) { 28 int len = 0; 29 while(x) a[++len] = x % 10, x /= 10; 30 return dfs(len, 0, 0, true, true); 31 } 32 33 int main() 34 { 35 ll l, r; 36 ll ans = 0; 37 scanf("%lld%lld", &l, &r); 38 for(int i = 1; i <= tot; ++i) { 39 mod = i; 40 memset(sum, -1, sizeof(sum)); 41 ans += work(r) - work(l - 1); 42 } 43 printf("%lld\n", ans); 44 }