BZOJ 1799 - [AHOI2009]self 同类分布 - 枚举 数位DP

本文介绍了一种使用数位动态规划(DP)解决数论中特定问题的方法:在给定区间[L,R]内,寻找所有各位数字之和能整除其本身的数的数量。通过枚举可能的数字和,利用数位DP高效地遍历所有可能性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 }
View Code

 

转载于:https://www.cnblogs.com/cychester/p/9649812.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值