码迷,mamicode.com
首页 > 其他好文 > 详细

HDU-4389 X mod f(x) && 2018上海大都会邀请赛J 数位dp

时间:2018-07-23 16:26:59      阅读:255      评论:0      收藏:0      [点我收藏+]

标签:数字   font   show   技术分享   memset   pre   include   分享   class   

题意:给出区间【L,R】,求其中有多少个数满足自身被数位和整除

比赛出了刚好没刷的原题系列= =

思路:枚举的过程中很好记录数位和,但是一个数字可以很大(1e9、1e12),不能加到状态里

既然相对很小的量是数位和,考虑枚举最终的数位和作为模数,用它来模过程中得到的数字num,这样num就可以加入状态了

最后只要枚举到的数位和确实是这个模数,就是一个可行解,明确状态之后套模板即可

技术分享图片
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 int a[10], dp[10][90][90][90];
 7 
 8 int dfs(int pos, int sum, int mod, int res, bool lim){
 9     if (pos == -1) return (sum == 0 && res == mod);
10     if (!lim && dp[pos][sum][mod][res] != -1) return dp[pos][sum][mod][res];
11     int r = lim ? a[pos] : 9;
12     int ans = 0;
13     for (int i = 0; i <= r; i++){
14         ans += dfs(pos-1, (sum*10+i)%mod, mod, res+i, lim && i == a[pos]);
15     }
16     if (!lim) dp[pos][sum][mod][res] = ans;
17     return ans;
18 }
19 
20 int solve(int x){
21     int pos = 0;
22     while (x){
23         a[pos++] = x%10;
24         x /= 10;
25     }
26     int ans = 0;
27     for (int i = 1; i <= 81; i++)
28         ans += dfs(pos-1, 0, i, 0, 1);
29     return ans;
30 }
31 
32 int main(){
33     int t, a, b, kase = 0;
34     scanf("%d", &t);
35     memset(dp, -1, sizeof dp);
36     while (t--){
37         scanf("%d%d", &a, &b);
38         printf("Case %d: %d\n", ++kase, solve(b)-solve(a-1));
39     }
40     return 0;
41 }
View Code

 

HDU-4389 X mod f(x) && 2018上海大都会邀请赛J 数位dp

标签:数字   font   show   技术分享   memset   pre   include   分享   class   

原文地址:https://www.cnblogs.com/QAQorz/p/9355200.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!